2017-10-19 133 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属性,因为您不需要它,因为您的集合已经暗示该类型。
  • 为什么要将表/列名放入方括号?他们使代码不可读,我不认为使用它的好处。