无法使用生成标识列键 (表_每_类)

发布于 2024-07-21 20:40:30 字数 1222 浏览 5 评论 0原文

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

对我来说生成身份证? 我不想改变我的继承策略。

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

Gives me this exception:

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

What's the best and most convenient way for me to generate the ID's? I do not want to change my inheritance strategy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

悟红尘 2024-07-28 20:40:30

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

尝试:

@GenerateValue(strategy = GenerationType.TABLE)

The problem here is that you mix "table-per-class" inheritance and GenerationType.Auto.
Consider an identity column in MsSQL. It is column based. In a "table-per-class" strategy you use one table per class and each one has an ID.

Try:

@GeneratedValue(strategy = GenerationType.TABLE)

岁吢 2024-07-28 20:40:30

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

视频如下:https://www.youtube.com/watch?v=qIdM4KQOtH8

I wonder if this is a database dialect specific problem, since watching a youtube tutorial with PostgreSQL as the underlying database I saw that the creator of the video run succefully an app with the default @GeneratedValue. In my case (the underlying database is MySQL) I had to modify the @GeneratedValue strategy to GenerationType.TABLE exactly as zoidbeck proposes.

Here is the video : https://www.youtube.com/watch?v=qIdM4KQOtH8

森罗 2024-07-28 20:40:30

同意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值将自动递增并用于所有实现子类表的新记录。

Agree with zoidbeck's answer.
You need to change strategy to:

@GeneratedValue(strategy = GenerationType.TABLE)

But that's not all, you need to create a new table, what will hold your abstract's table primary key sequence. Modify your mapping to

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

And a new table in database should look like following:
enter image description here

When you ran your application, Hibernate will insert a row where sequence_name will be the entity name (SuperClass in this example) and sequence_next_hi_value value will be automatically incremented and used for new records of all implementing subclasses's tables.

ら栖息 2024-07-28 20:40:30

您可以使用@MappedSuperclass进行继承

you can use @MappedSuperclass for inheritance

北城挽邺 2024-07-28 20:40:30

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

因此,对我们有用的解决方案是显式使用 GenerationType.SEQUENCE

In our case, we use a PostreSQL database for dev and production and an in-memory hsqldb database for tests. We are using a sequence in both cases to generate an id. Apparently GenerationType.AUTO defaults to SEQUENCE for postgres, but failed in our local tests (must default to something else for hsqldb).

So the solution that worked for us, explicitly use GenerationType.SEQUENCE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文