有没有一种方法可以使用JPA注释和Hibernate动态选择@GeneratedValue策略?

20
我正在开发一个产品,将支持多个数据库引擎(Oracle、MSSQL、MySQL)。对于Oracle,我更倾向于使用序列(Sequences),而不是序列表(Sequence table),以避免在高负载环境下可能出现的并发和锁定问题,但其他数据库引擎不支持序列。此外,我更倾向于为每个表使用一个序列,而不是全局序列(例如hibernate_sequence),因此@GeneratedValue(strategy = GenerationType.AUTO)无法使用。有没有办法在运行时动态选择策略?
1个回答

40
实际上,Hibernate使用其org.hibernate.id.enhanced.SequenceStyleGenerator来解释GenerationType.AUTO和GenerationType.SEQUENCE。SequenceStyleGenerator是一种ID生成策略,根据底层数据库支持的内容选择两种策略之一。如果数据库支持序列,则SequenceStyleGenerator使用序列;否则,它将回退到使用“序列表”。控制哪种生成器要使用的“映射”由一个设置控制:hibernate.id.new_generator_mappings。将其设置为true可以启用我刚才描述的行为。不幸的是,出于向后兼容性的原因,我们不得不将其默认设置为false。因此,要利用这个功能,您需要确保该设置已设置为true。
此外,您可以配置SequenceStyleGenerator,以便在不给出名称的情况下优先使用全局序列或每个实体序列。这由名为prefer_sequence_per_entity的设置控制。
总的来说,SequenceStyleGenerator是非常可配置的。详细信息请查看其javadoc:http://docs.jboss.org/hibernate/orm/4.1/javadocs/index.html?org/hibernate/id/enhanced/SequenceStyleGenerator.html

它如何进行配置?我还没有找到任何更改SequenceStyleGenerator的increment_size的示例?传递给configure方法的参数是cfg.xml中设置的一组有限属性。优化器和increment_size都不是我所努力传递的。 - Eyad Ebrahim
2
@SequenceGenerator( ..., allocationSize=blah ) - Steve Ebersole
谢谢您的建议。但是似乎这是一种捷径,因为SequenceGenerator没有SequenceStyleGenerator中提到的相同配置属性。我尝试了这个方法,并且在使用Pooled Optimizer时它给了我期望的性能优势。但是为了结束这个话题,有没有一种在cfg.xml文件中实现的方法?当我调试时,SequenceStyleGenerator.java中的“optimizer”和“increment_size”并没有被Hibernate读取。 https://dev59.com/lnjZa4cB1Zd3GeqPfpb1 - Eyad Ebrahim
1
当仅使用strategy=SEQUENCE + @SequenceGenerator时,如何将prefer_sequence_per_entity参数传递给SequenceStyleGenerator?是否有比回退到@GeneratedValue(generator="mygen")然后@GenericGenerator(name="mygen", strategy="org.hibernate.id.enhanced.SequenceStyleGenerator", parameters=...)更短的方法? - Marko Topolnik
1
从Hibernate 5开始,“hibernate.id.new_generator_mappings”默认设置为true:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html - Kayvan Tehrani
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接