104

com.something.SuperClass:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class SuperClass implements Serializable {
    private static final long serialVersionUID = -695503064509648117L;

    long confirmationCode;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!!
    public long getConfirmationCode() {
        return confirmationCode;
    }

    public void setConfirmationCode(long confirmationCode) {
        this.confirmationCode = confirmationCode;
    }
}

com.something.SubClass:

@Entity
public abstract class Subclass extends SuperClass {
    private static final long serialVersionUID = 8623159397061057722L;

    String name;

    @Column(nullable = false)
    public String getName() {
        return name;
    }

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

给了我这个例外:

Caused by: org.hibernate.MappingException: Cannot use identity column key
generation with <union-subclass> mapping for: com.something.SuperClass

我生成 ID 的最佳和最方便的方法是什么?我不想改变我的继承策略。

4

5 回答 5

242

这里的问题是你混合了“每类表”继承和GenerationType.Auto. 考虑 MsSQL 中的标识列。它是基于列的。在“每类表”策略中,每个类使用一个表,每个表都有一个 ID。

尝试:

@GeneratedValue(strategy = GenerationType.TABLE)

于 2009-05-28T22:29:58.830 回答
8

我想知道这是否是特定于数据库方言的问题,因为观看了以 PostgreSQL 作为基础数据库的 youtube 教程,我看到视频的创建者成功地运行了具有默认 @GeneratedValue 的应用程序。在我的情况下(底层数据库是 MySQL),我必须完全按照 zoidbeck 的建议将 @GeneratedValue 策略修改为 GenerationType.TABLE。

这是视频:https ://www.youtube.com/watch?v=qIdM4KQOtH8

于 2013-03-10T15:52:03.337 回答
7

同意zoidbeck的回答。您需要将策略更改为:

@GeneratedValue(strategy = GenerationType.TABLE)

但这还不是全部,您需要创建一个新表,它将保存您的摘要表的主键序列。将您的映射修改为

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator")
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator")
public long getConfirmationCode() {
   return confirmationCode;
}

数据库中的新表应如下所示: 在此处输入图像描述

当您运行您的应用程序时,Hibernate 将插入一行sequence_name作为实体名称(SuperClass在本例中)并且sequence_next_hi_value值将自动递增并用于所有实现子类表的新记录。

于 2015-06-21T13:32:36.810 回答
2

在我们的例子中,我们使用 PostreSQL 数据库进行开发和生产,使用内存中的 hsqldb 数据库进行测试。在这两种情况下,我们都使用序列来生成 id。显然GenerationType.AUTO默认SEQUENCE为 postgres,但在我们的本地测试中失败(对于 hsqldb,必须默认为其他东西)。

所以对我们有用的解决方案,明确地使用GenerationType.SEQUENCE.

于 2014-08-06T21:01:58.807 回答
2

您可以使用@MappedSuperclass 进行继承

于 2017-04-07T02:08:16.820 回答