为了账号安全,请及时绑定邮箱和手机立即绑定

带一个自增的Spring JPA复合PK

带一个自增的Spring JPA复合PK

POPMUISE 2022-12-15 16:49:37
我正在尝试使用 Spring Boot 2.1.2.RELEASE + JPA(使用启动器)和 MySQL (InnoDB) 来保留具有复合主键的实体,其中一个应该自动递增。我有一个带有 2 个非抽象子类的抽象类,我正在使用单表策略进行继承。我一直在寻找如何实现这一点,但每一篇似乎都在寻找与我相同的帖子最终都没有答案(示例)。我当前的设置如下所示(为清楚起见省略了 setter、getter 和构造函数)。@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@IdClass(MyEntityPK.class)public abstract class MyEntity {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    long pk1; //Should be auto-incremented    @Id    OffsetDateTime pk2;    //More fields...public class MyEntityPK implements Serializable {   private static final long serialVersionUID = 1L;   long pk1;   OffsetDateTime pk2;}@Repositorypublic interface MyEntityRepository extends CrudRepository<MyEntity, MyEntityPK> {   //Some methods like save().}我发现的第一个问题是表格生成。如果声明如下,MySQL 允许创建 PKPRIMARY KEY (pk1, pk2)但不是以不同的顺序PRIMARY KEY (pk2, pk1)创建表时,Hibernate 使用第二个,因此失败。还尝试更改字段顺序但无济于事。我认为这可能是 Hibernate 的问题,但我不确定。任何人都可以确认吗?不管怎样,我通过手动创建 DDL 脚本并通过 Hibernate 禁用自动 DDL 解决了这个问题。下一个问题,我没有找到答案,是实体被正确保存在表中,但是存储库的保存方法返回的 id 始终为 0。我在保存之前手动设置 pk2,而保留 pk1由DB完成。entity.setPk2(OffsetDateTime.now());Entity savedEntity = repository.save(entity); //savedEntity has id 1 in table but 0 in code在调试时,我到达了这个isNew() 方法。事实证明它返回 false,因为 MyEntityPK 与 null 不同(我设置了 pk2)。这当然不是我所期望的,因为我实际上是在保存一个新实体,因为我的 PK 是复合的并且我将一个字段留空。所以,我也认为这可能是一个错误。有一些类覆盖了 isNew() 方法,但它们似乎没有被使用。我做错了什么还是这是一个错误?帮助赞赏:)
查看完整描述

1 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

不支持 @EmbededId 或 @IdClass 上的 @GeneratedValue(strategy = GenerationType.IDENTITY)。

这是一个与您的请求完全相关的错误,该错误被休眠https://hibernate.atlassian.net/browse/ANN-268拒绝

这是另一个更新的错误报告。请注意 Vlad Mihalcea 评论:

这不是一个障碍,它只是一个主要问题。例如,JPA 规范甚至没有说明复合标识符中是否允许生成的标识符。

无论如何,这仅适用于具有基于序列的标识符的 @IdClass,如本文所述。

https://hibernate.atlassian.net/browse/HHH-9662

引文中的文章解释了如何将 @GeneratedValue(strategy = GenerationType.SEQUENCE) 映射到复合材料上。


查看完整回答
反对 回复 2022-12-15
  • 1 回答
  • 0 关注
  • 64 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信