2017-10-19 1 views
0

Kürzlich habe ich eine sehr ähnliche Frage auf Stack Overflow gestellt, die sich als ein Duplikat einer anderen Frage erwies. In dieser anderen Frage gab es einen Workaround, den ich angewendet und mein Problem gelöst habe. Jetzt funktioniert die Problemumgehung nicht und alle anderen erwähnten Lösungen funktionieren nicht. Außerdem funktionieren alle Lösungen von anderen Threads, die mit dem ersten Thread verknüpft sind, nicht.JPA: Löschen Waisen, ungültige Spalte

Das war meine Frage zuerst:

SQLServerException: Invalid column name

Und dies war die Verdoppelung:

hibernate column name issues

ich die Themen auf der rechten Seite in den verknüpften und Verwandte Abschnitte geprüft haben, aber finde keine Lösung für mein Problem. Ich kann auch nicht verstehen, warum mein Problem auftritt.

Ich habe 2 Tabellen: Erklärung und Datei (Ich werde nicht meine andere Tabellen hier erwähnen, weil sie das Problem nicht relevant ist)

CREATE TABLE [dbo].[Declaration] (
    [number]   INT   NOT NULL, 
    [status]   VARCHAR (50) NOT NULL, 
    [name]    VARCHAR (50) NOT NULL, 
    [description]  VARCHAR (250) NOT NULL, 
    [amount]   FLOAT (53) NOT NULL, 
    [date]    DATE   NOT NULL, 
    [period_id]   INT   NOT NULL, 
    [client_project_id] INT   NOT NULL, 
    PRIMARY KEY CLUSTERED ([number] ASC), 
    CONSTRAINT [fk_client_period] FOREIGN KEY ([client_project_id]) REFERENCES [dbo].[ClientProject] ([number]), 
    CONSTRAINT [fk_period] FOREIGN KEY ([period_id]) REFERENCES [dbo].[Period] ([number]) 
); 

CREATE TABLE [dbo].[File] (
    [number] INT   NOT NULL, 
    [path] VARCHAR (50) NOT NULL, 
     [declaration_id] INT NOT NULL, 
     PRIMARY KEY CLUSTERED ([number] ASC), 
CONSTRAINT [fk_file] FOREIGN KEY ([declaration_id]) REFERENCES [dbo].[Declaration] ([number]) 
    ); 

Mit den entsprechenden Klassen:

@Entity 
@Table(name = "[file]") 
public class File { 

    @Id 
    private int number; 
    private String path; 

    @ManyToOne(targetEntity = Declaration.class) 
    private int declaration_id; 

    public int getDeclaration_id() { 
     return declaration_id; 
    } 

    public void setDeclaration_id(int declaration_id) { 
     this.declaration_id = declaration_id; 
    } 

    public int getNumber() { 
     return number; 
    } 

    public void setNumber(int number) { 
     this.number = number; 
    } 

    public String getPath() { 
     return path; 
    } 

    public void setPath(String path) { 
     this.path = path; 
    } 
} 

Und

@Entity 
public class Declaration { 

    @Id 
    private int number; 
    private String status; 
    private String name; 
    private String description; 
    private double amount; 
    private Date date; 
    private int period_id; 
    private int client_project_id; 

    @OneToMany(targetEntity = File.class,mappedBy = "declaration_id",orphanRemoval = true) 
    private List<File> files = new ArrayList<>(); 

    public List<File> getFiles() { 
     return files; 
    } 

    public void setFiles(List<File> files) { 
     this.files = files; 
    } 

    public int getNumber() { 
     return number; 
    } 

    public void setNumber(int number) { 
     this.number= number; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public void setStatus(String status) { 
     this.status = status; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public double getAmount() { 
     return amount; 
    } 

    public void setAmount(double amount) { 
     this.amount = amount; 
    } 

    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

    public int getPeriod_id() { 
     return period_id; 
    } 

    public void setPeriod_id(int period_id) { 
     this.period_id = period_id; 
    } 

    public int getClient_project_id() { 
     return client_project_id; 
    } 

    public void setClient_project_id(int client_project_id) { 
     this.client_project_id = client_project_id; 
    } 
} 

Ich habe meine @ManyToOne und @OneToMany definiert Beziehungen auf der Grundlage dieser Themen und Anleitungen:

https://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/

JPA JoinColumn vs mappedBy

Was ich will: Erklärung löschen, Dateien automatisch auf die Erklärung

bezogen löschen

Was ich bekomme: Ungültiger Spaltenname 'declaration_id_number'.

Was habe ich versucht:

- renaming fields in database to declaration_id_number (results in declaration_id_number_number) 
- using @Column(name="declaration_id") on declaration_id field 
- using @Colum(name="declaration_id") on the getter field 
- using @JoinColumn(name="fk_file") on the declaration_id field 
- Using different kinds of naming stategies (in application.properties), including the default one 

spring.jpa.hibernate.naming.strategy: org.hibernate.cfg.EJB3NamingStrategy 
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl 
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 

Die tatsächliche SQL-Abfrage:

select files0_.declaration_id_number as declarat3_3_0_, files0_.number as number1_3_0_, files0_.number as number1_3_1_, files0_.declaration_id_number as declarat3_3_1_, files0_.path as path2_3_1_ from [file] files0_ where files0_.declaration_id_number=? 


select declaratio0_.number as number1_2_0_, declaratio0_.amount as amount2_2_0_, declaratio0_.client_project_id as client_p3_2_0_, declaratio0_.date as date4_2_0_, declaratio0_.description as descript5_2_0_, declaratio0_.name as name6_2_0_, declaratio0_.period_id as period_i7_2_0_, declaratio0_.status as status8_2_0_ from declaration declaratio0_ where declaratio0_.number=? 

Ich bin mit Federschuh mit JPA Hibernate 5.2.10

Gibt es jemanden da draußen, weiß warum das passiert, wenn ich weiß, warum es passiert, könnte ich in der Lage sein, das Problem selbst zu beheben. Gerade jetzt bin ich völlig fest.

Vielen Dank im Voraus.

EDIT:

Ok, also zufällig ich mein eigenes Problem gelöst, ich weiß noch nicht, warum das Problem in erster Linie aufgetreten.Nach dieser Antwort (en) dieses Thema:

JPA JoinColumn vs mappedBy

verwenden Sie @ManyToOne & @OnyToMany

In meinem Fall muss ich nicht @ManyToOne in der File-Klasse verwenden . Ich brauche nur @OneToMany in meiner Deklarationsklasse. Nach dem Entfernen dieser Anmerkung treten keine weiteren Fehler auf.

Wenn jemand den Grund für dieses Problem kennt, geben Sie bitte eine Antwort, damit es in Zukunft für mich oder jemand anderen nützlich sein kann.

+0

Ihre Frage ist ziemlich durcheinander. Es ist nicht klar, welchen Code Sie gerade ausgeführt haben.Sagen Sie uns, was Sie genau gemacht haben: "Ungültiger Spaltenname 'declaration_id_number'". Warum enthält Ihre Abfrage zwei Abfragen? Sie sind auch keine Abfragen, sie sind Vorlagen. Außerdem ist nicht klar, wie wir Ihre Liste von "Was ich versucht habe" zu verstehen, dh welchen Code Sie für jeden ausgeführt hätten, und warum die letzten drei Zeilen da sind. Bitte lesen und handeln Sie auf [mcve]. – philipxy

Antwort

0

In meinem Fall muss ich @ManyToOne nicht in der Klasse File verwenden. Ich brauche nur @OneToMany in meiner Deklarationsklasse. Nach dem Entfernen dieser Anmerkung treten keine weiteren Fehler auf.

Ich glaube nicht, dass dies funktioniert. Wenn Sie die Annotation @ManyToOne entfernen, erstellt der Persistenzanbieter standardmäßig eine Join-Tabelle, um die Beziehung beizubehalten. Was Sie meinen, ist wahrscheinlich, dass Sie keine Ausnahme bekommen. Aber schauen Sie sich das Datenbankschema:

CREATE TABLE [dbo].[File] (
    [number] INT   NOT NULL, 
    [path] VARCHAR (50) NOT NULL, 
    [declaration_id] INT NOT NULL, 
    PRIMARY KEY CLUSTERED ([number] ASC), 
    CONSTRAINT [fk_file] FOREIGN KEY ([declaration_id]) REFERENCES [dbo].[Declaration] ([number]) 
); 
  • declaration_id ist declaraed NOT NULL zu sein, was bedeutet, dass Sie nicht alles, was in dieser Tabelle speichern können, wenn Sie es einen Eintrag in der Tabelle Declaration zuweisen.
  • Sie haben eine Fremdschlüsseleinschränkung definiert, was bedeutet, dass Ihre Datenbank dies beim Speichern eines Dateieintrags überprüft.

Dies bedeutet, dass Sie zwei Möglichkeiten:

  • Sie eine @ManyToOne Anmerkung benötigen, so dass JPA die Entitäten korrekt und dass Ihr Datenbankschema entsprechen wird automatisch zuordnen kann, oder

  • Sie entfernen das Fremdschlüsselfeld declaration_id und die entsprechende referenzielle Integritätsbedingung aus der File-Tabelle. In diesem Fall erstellt der Persistenzanbieter standardmäßig eine Join-Tabelle für Sie, sofern Sie diese nicht anpassen.

Also, wenn Sie die erste Option, dh @ManyToOne Annotation verwenden möchten, haben Sie die Einheiten auf der Karte wie folgt:

@Entity 
@Table(name = "[file]") 
public class File { 

    @Id 
    private int number; 
    private String path; 

    @ManyToOne 
    @JoinColumn(name = "declaration_id") 
    private Declaration declaration; 

    public int getDeclaration_id() { 
     return declaration_id; 
    } 

    // ... getters and setters 
} 

und eine leicht modifizierte Declaration Einheit:

@Entity 
public class Declaration { 

    @Id 
    private int number; 
    // ... other fields 

    @OneToMany(mappedBy = "declaration",orphanRemoval = true) 
    private List<File> files = new ArrayList<>(); 

    // ... Rest of the code 
} 

Anmerkungen:

  • Ich habe das Attribut targetEntity = File.class aus der Anmerkung entfernt, weil Sie es nicht benötigen, da Ihre Sammlung den Typ bereits voraussetzt.
  • Warum setzen Sie Tabellen-/Spaltennamen in die eckigen Klammern? Sie machen den Code unlesbar und ich sehe keinen Nutzen darin.