Hibernate 5中SequenceGenerator名称是否全局唯一?版本升级技术问询
Hibernate 5.2.13 升级中的 SequenceGenerator 名称问题
嘿,针对你从Hibernate 4.3升级到5.2.13遇到的这个实体继承+序列生成器的问题,我来给你理清楚~
你的场景还原
首先把你提到的实体结构用代码还原出来,方便理解:
// 带注解的抽象父类 Identity public abstract class Identity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "IdSequenceGenerator") private Long id; // 其他通用属性和方法 } // 实体A @AttributeOverride(name = "id", column = @Column(name = "table_a_id")) @Entity @SequenceGenerator(name = "IdSequenceGenerator", sequenceName = "table_a_seq") @Table(name = "table_a") public class EntityA extends Identity { // EntityA专属属性和方法 } // 实体B @AttributeOverride(name = "id", column = @Column(name = "table_b_id")) @Entity @SequenceGenerator(name = "IdSequenceGenerator", sequenceName = "table_b_seq") @Table(name = "table_b") public class EntityB extends Identity { // EntityB专属属性和方法 }
核心问题解答:SequenceGenerator 的名称是否全局唯一?
在 Hibernate 5 中,SequenceGenerator 的名称是全局唯一的——这个名称在整个持久化单元(也就是你的项目中所有关联的实体、持久化配置范围内)不能重复。
这其实是严格遵循 JPA 规范的要求:@SequenceGenerator 的 name 属性是一个全局标识符,用来和 @GeneratedValue 中的 generator 属性做关联匹配。如果多个生成器用了同一个名称,Hibernate 启动时会直接抛出类似 org.hibernate.DuplicateMappingException: Duplicate generator name 的异常,因为它没法区分不同的生成器实例。
针对你场景的解决方案
你现在的问题就是 EntityA 和 EntityB 都用了 name = "IdSequenceGenerator",这在 Hibernate 5 里肯定会冲突。解决办法很简单:给每个实体的序列生成器设置唯一的名称,同时确保子类的 @GeneratedValue 指向自己的生成器(注意:JPA 注解默认不会被子类继承,所以子类需要重新标注 @GeneratedValue 来覆盖父类的配置)。
调整后的代码示例:
// 优化后的抽象父类(去掉固定的generator名称,让子类自行指定) public abstract class Identity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; // 其他通用属性和方法 } // 实体A修改后 @Entity @SequenceGenerator(name = "EntityAIdGenerator", sequenceName = "table_a_seq") @Table(name = "table_a") public class EntityA extends Identity { // 重新标注id字段,指定自己的生成器和列名 @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EntityAIdGenerator") @Column(name = "table_a_id") private Long id; // EntityA专属属性和方法 } // 实体B修改后 @Entity @SequenceGenerator(name = "EntityBIdGenerator", sequenceName = "table_b_seq") @Table(name = "table_b") public class EntityB extends Identity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EntityBIdGenerator") @Column(name = "table_b_id") private Long id; // EntityB专属属性和方法 }
这样每个生成器的名称都是唯一的,就不会再触发冲突了。
内容的提问来源于stack exchange,提问作者Kramer
相关产品推荐
相关产品推荐

