2017-10-19 463 views
0

最近我問了一個關於堆棧溢出的非常類似的問題,結果是另一個問題的重複。在另一個問題中,我採用了一種解決方法,解決了我的問題。現在,這一次解決方法不起作用,並且所有其他提到的解決方案都不起作用。此外,鏈接到第一個線程的其他線程的所有解決方案都不起作用。JPA:刪除孤兒,無效列

這是我的第一個問題:

SQLServerException: Invalid column name

這是重複:

hibernate column name issues

我已經檢查了主題上的鏈接和相關內容,正確的,但找不到解決我的問題。我也無法理解我的問題出現的原因。

我有2個表:宣言文件(我不會提及我的其他表在這裏,因爲他們是無關的問題)

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]) 
    ); 

與相應的類:

@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; 
    } 
} 

And

@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; 
    } 
} 

基於這些主題和教程我已經定義我的@ManyToOne和@OneToMany關係:

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

JPA JoinColumn vs mappedBy

我想要什麼:刪除宣言,自動刪除相關的聲明文件

我得到:列名'declaration_id_number'無效。

我曾嘗試:

- 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 

實際的SQL查詢:

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=? 

我正在春天開機使用JPA休眠5.2.10

有沒有人在那裏誰知道爲什麼這發生,如果我知道它爲什麼發生,我可能能夠解決我自己的問題。現在我完全卡住了。

在此先感謝。

編輯:

好了,偶然我解決我自己的問題,我仍然不知道爲什麼這個問題擺在首位發生。根據這一話題的這個答案(S):

JPA JoinColumn VS的mappedBy

您使用@ManyToOne & @OnyToMany

在我來說,我不需要在文件類中使用@ManyToOne 。我的宣言課只需要@OneToMany。刪除此註釋後不會再出現任何錯誤。

如果有人知道這個問題的原因,請提供一個答案,以便將來可以爲我或其他人使用。

+0

你的問題是相當混亂。目前還不清楚你運行的是什麼代碼。告訴我們你做了什麼「獲取:無效的列名'declaration_id_number'」。爲什麼你的查詢有兩個查詢?此外,他們不是查詢,他們是模板。另外,還不清楚我們是如何理解你的「我所嘗試過的」列表的,也就是說你會爲每一個代碼運行什麼代碼,以及爲什麼最後三行代碼在那裏。請閱讀並在[mcve]上採取行動。 – philipxy

回答

0

在我的情況下,我不需要在File類中使用@ManyToOne。我的宣言課只需要@OneToMany。刪除此註釋後不會再出現任何錯誤。

我不認爲這會奏效。如果您刪除@ManyToOne註釋,則持久性提供程序將默認創建連接表以維護關係。你的意思可能是你沒有得到任何例外。但看看數據庫模式:

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被declaraed是NOT NULL這意味着你無法保存任何在該表中,除非你給它分配在Declaration表中的條目。
  • 您已經定義了外鍵約束,這意味着當您保存文件記錄時,數據庫將檢查該約束。

這意味着,你有兩個選擇:

  • 你需要一個@ManyToOne註釋,使JPA能夠正確映射實體,並自動將符合您的數據庫架構,或

  • 您從File表中刪除外鍵字段declaration_id和相應的參照完整性約束。在這種情況下,除非您自定義,否則默認情況下,持久性提供程序會爲您創建連接表。

所以,如果你想使用第一個選項,即@ManyToOne批註,您必須將實體如下圖:

@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 
} 

和稍微修改Declaration實體:

@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 
} 

備註:

  • 我從註釋中刪除了targetEntity = File.class屬性,因爲您不需要它,因爲您的集合已經暗示該類型。
  • 爲什麼要將表/列名放入方括號?他們使代碼不可讀,我不認爲使用它的好處。