无法在 JPA 中使用 TABLE_PER_CLASS 策略生成标识列键?

Posted

技术标签:

【中文标题】无法在 JPA 中使用 TABLE_PER_CLASS 策略生成标识列键?【英文标题】:Cannot use identity column key generation with the strategy TABLE_PER_CLASS in JPA? 【发布时间】:2012-01-07 06:32:55 【问题描述】:

这个问题与this thread 中提到的问题有关。 在 mysql 上使用 JPA 时,我也面临同样的问题。只有当我将生成策略更改为 TABLE 时才能解决它。

但问题是,这个问题背后的原因是什么以及为什么将策略更改为 TABLE 是解决方案(这在the thread 中仍未得到解答)?

【问题讨论】:

【参考方案1】:

要通过继承层次结构(JPA 要求)拥有唯一的 id,显然不能使用 TABLE_PER_CLASS 和 IDENTITY 来做到这一点,因为 IDENTITY 对一个表起作用,并且继承层次结构中现在有多个“根”表。

例如抽象基类“Base”和子类“Sub1”、“Sub2”、“Sub3”。 所以你有实际的表“SUB1”、“SUB2”、“SUB3”。因此,如果使用 IDENTITY,那么这将等同于使用 MySQL 时列上的“自动增量”。因此 SUB1 有它的 ids,SUB2 有它的 ids,SUB3 有它的 ids ......它们是独立的,因此可能会在 id 中发生冲突......所以你在继承层次结构中不再有唯一的 id。

【讨论】:

【参考方案2】:

如果你想在类之间共享一些属性,你可以使用@MappedSuperclass给超类,这不会影响子类Id的生成策略。它只是将所有注释复制到子类

@MappedSuperclass
public class BaseEntity 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(columnDefinition = "TIMESTAMP")
    private Date createTime = new Date();


    public long getId() 
        return id;
    

    public void setId(long id) 
        this.id = id;
    

    public Date getCreateTime() 
        return createTime;
    

    public void setCreateTime(Date createTime) 
        this.createTime = createTime;
    

【讨论】:

【参考方案3】:

接受的答案(虽然旧)并不完全正确。使用 GenerationType.IDENTITY 并不意味着数据库使用表生成。 GenerationType.IDENTITY 的 javadoc 说:“表明持久性提供者必须使用数据库标识列为实体分配主键。”。

【讨论】:

以上是关于无法在 JPA 中使用 TABLE_PER_CLASS 策略生成标识列键?的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring JPA 休眠中获取关系

Spring JPA无法提交jdbc事务的解决办法

无法使用 JPA 查询检索结果

“where”条件在 JPA 中的联接查询中无法正常工作(本机查询)

无法使用 JPA 2.0、Spring 2.5.6、Hibernate 3.6.1 和 Maven 在 HSQLDB 中持久化

Glassfish - 无法使用 JPA 删除实体