我正在尝试使用 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;
}
@Repository
public interface MyEntityRepository extends CrudRepository<MyEntity, MyEntityPK> {
//Some methods like save().
}
我发现的第一个问题是表生成。如果声明如下,MySQL 允许创建 PK
PRIMARY KEY (pk1, pk2)
但不是以不同的顺序
PRIMARY KEY (pk2, pk1)
创建表时,Hibernate 使用第二个,因此失败。还尝试更改字段顺序但无济于事。我认为这可能是 Hibernate 的一个问题,但我不确定。任何人都可以确认吗?无论如何,我通过手动创建 DDL 脚本并通过 Hibernate 禁用自动 DDL 解决了这个问题。
下一个问题,我没有找到答案,实体在表中正确保存,但是存储库的save方法返回的id始终为0。我在保存之前手动设置pk2,而离开pk1由数据库完成。
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() 方法,但似乎它们没有被使用。
我做错了什么还是这是一个错误?帮助表示赞赏:)