我已将休眠版本从 4.0.1.Final 更新到 5.0.7.Final(从 Jboss 7 移植到 Wildfly 10)。
问题: hibernate 框架使用 hibernate_sequence 来生成 id 而不是 mySequence。
Hibernate 配置: 为了保持向后兼容性,将 hibernate.id.new_generator_mappings 配置为 false 值。
实体配置: id 字段使用以下 JPA API 进行注释:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "myGenerator")
@SequenceGenerator(name = "myGenerator", sequenceName = "MY_GENERATOR_SEQ")
@Column(name="ID")
private Long id;
DB 配置: MY_GENERATOR_SEQ 序列使用“INCREMENT BY 1”选项定义。
H2 和 Oracle DB 都会出现此问题。
问题:我已经分析了实现,但我不知道它是否可能是 Hibernate 的 BUG 或我为向后兼容性所做的任何可能的错误配置???
分析: Hibernate 在服务器启动期间进行了一些初始化:SequenceStyleGenerator.configure 方法将 QualifiedName sequenceName 定义为“hibernate_sequence”,因为它试图从 Properties 参数中获取值。在这一点上,我注意到 MY_GENERATOR_SEQ sequenceName 在运行时使用“sequence”键(sequence=MY_GENERATOR_SEQ)出现在 Properties 参数中,但检索策略(determineSequenceName)需要“sequence_name”作为键。因此,用于将序列名称设置为 Properties 参数的键来自已弃用的类 org.hibernate.id.SequenceGenerator.SEQUENCE,因为 hibernate.id.new_generator_mappings=false,但 SequenceStyleGenerator 类需要 org.hibernate.id.enhanced .SequenceStyleGenerator。
潜在的解决方案:
- 设置 SequenceGenerator allocationSize=1(不设置 hibernate.id.new_generator_mappings=false)
- 使用 INCREMENT BY 50 在数据库上创建序列 MY_GENERATOR_SEQ(不设置 hibernate.id.new_generator_mappings=false)
这两种解决方案都不适用于我的上下文。所以唯一适用的“解决方案”是这个:扩展用于Oracle和H2的方言并以这种方式覆盖getNativeIdentifierGeneratorClass方法:
@Override
public Class getNativeIdentifierGeneratorClass() {
if ( getIdentityColumnSupport().supportsIdentityColumns() ) {
return IdentityGenerator.class;
}
else {
//From hibernate-core 5.0.7.Final, org.hibernate.dialect.Dialect
//the original return value was org.hibernate.id.enhanced.SequenceStyleGenerator.class
return SequenceGenerator.class;
}
}
并使用 ah-hoc 方言在 org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter 上设置“databasePlatform”。
也提交给hibernate社区:https ://hibernate.atlassian.net/browse/HHH-10656