Hibernate - JPA 在不同的情况下生成具有相同名称的重复表

Posted

技术标签:

【中文标题】Hibernate - JPA 在不同的情况下生成具有相同名称的重复表【英文标题】:Hibernate - JPA generates duplicate tables with same name in different case 【发布时间】:2018-05-09 20:44:55 【问题描述】:

我正在重新学习 Hibernate 和 JPA。我在我的环境中使用 Spring Boot、Gradle 和 Postgres。我有一组访问 Postgres 数据库的域对象。两个对象不使用注解,使用 JDBCTemplate 类进行数据库操作。另一组域对象使用 JPA 注释。 JPA 对象集具有使用 JPA 注释映射出来的关系。当我运行单元测试以检查 JDBC 模板对象的数据库实体时,一切都很好。当我检查数据库时,我发现我有使用注释的那些域对象的重复实体。

我已查看我的注释和项目设置,但未能成功找到我的错误。

这是我的类定义:

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;

@Entity(name="AcceptanceCriteria")
@Table(name="accCriteria_tbl", schema="ia_req_changes")
@SequenceGenerator(name="AcceptCritera_SEQ_GEN", schema="ia_req_changes", sequenceName = "accCriteria_tbl_accCri_id_seq", initialValue = 1, allocationSize = 1)
public class AcceptanceCriteria implements Serializable

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="AcceptCritera_SEQ_GEN")
    @Column(name="accCri_id", updatable = false)
    private Long accCri_id;

    @Column(name="accAction")
    private String accAction;
    @Column(name="accControl")
    private String accControl;
    @Column(name="accAccptCriteria")
    private String accAccptCriteria;
    @Column(name="lastModified")
    private Timestamp lastModified;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FK_funcReq_id", referencedColumnName = "funcReq_id")
    private FunctionalRequirement functionalReq;


    public AcceptanceCriteria() 
    

这是来自 Postgres 的表格。明显的区别是我使用 DDL 创建的表是具有大写表名的表。

任何建议或建议将不胜感激。

谢谢,

罗斯

【问题讨论】:

【参考方案1】:

在 Postgres 中,可以使用双引号创建区分大小写名称的表(和列)。例如,创建一个表

create table some_case (id bigint);

尝试重新创建它

create table Some_Case (id bigint);

结果是

错误:关系“some_case”已经存在

但用双引号。

create table "Some_Case" (id bigint);

它有效,您最终会遇到现在的情况。我猜想具有大写字母的表是故意以这种方式创建的,它在您的 JDBC 模板中的工作方式是这样的吗? 请参阅此相关帖子:Are PostgreSQL column names case-sensitive?

JPAs @Table 注解中声明表名时,它总是降为小写。为了处理这种情况,可能会有类似这篇文章描述的调整Spring boot JPA insert in TABLE with uppercase name with Hibernate

但是,如果可能的话,最好的做法是遵循“事实上的”约定,全部小写。换句话说,将数据从大写表复制到小写表,删除大写表并检查 JDBC 模板类,如果它们因此需要任何修改。

搜索 Stack Overflow 还提供了其他解决方案。

将转义的双引号添加到“@Table”注释也可能有效,例如

@Table(name="\"accCriteria_tbl\""

见this answer。从长远来看,仍然可能不是最好的解决方案。

【讨论】:

谢谢@pirho!重构表格和注释后,一切都消失了。

以上是关于Hibernate - JPA 在不同的情况下生成具有相同名称的重复表的主要内容,如果未能解决你的问题,请参考以下文章

在不同情况下使用不同的 Hibernate 用户类型

在不同情况下使用不同的 Hibernate 用户类型

JPA 或 Hibernate - 在不同类型的列上连接表

如何在不使用 JPA 的情况下保持在 SpringBoot/GraphQL 中打开的 Hibernate 事务?

hibernate JPA:可选值生成

如何在不依赖数据库的情况下使用 Hibernate 5 (JPA) 启动 Spring Boot Application 2?