如何让 Hibernate 在 Oracle 上将 SequenceHiLoGenerator 用于 JPA GenerationType.AUTO?

Posted

技术标签:

【中文标题】如何让 Hibernate 在 Oracle 上将 SequenceHiLoGenerator 用于 JPA GenerationType.AUTO?【英文标题】:How to make Hibernate to use SequenceHiLoGenerator for JPA GenerationType.AUTO on Oracle? 【发布时间】:2016-04-21 17:03:29 【问题描述】:

我有一个如下 id 的表,但是 hibernate 使用 org.hibernate.id.SequenceGenerator 而不是 SequenceHiLoGenerator 作为 GenerationType.AUTO,我如何告诉 hibernate 使用 SequenceHiLoGenerator?

@Id
@SequenceGenerator(name="admin_seq", sequenceName="unique_id")
@GeneratedValue(strategy=GenerationType.AUTO, generator="admin_seq")
private Long id

如果我使用 GenerationType.SEQUENCE,hibernate 将使用 SequenceHiLoGenerator,但我需要使用 GenerationType.AUTO 以与 mysql 兼容。

我尝试过使用@GenericGenerator,它适用于Oracle,但会被MySQL 抱怨:org.hibernate.dialect.MySQLDialect 不支持序列。

@GenericGenerator(name = "admin_seq", strategy = "org.hibernate.id.SequenceHiLoGenerator",
        parameters = 
                @Parameter(name = "sequence", value = "unique_id"),
                @Parameter(name = "max_lo", value = "50") )
@GeneratedValue(strategy=GenerationType.AUTO, generator="admin_seq")
private Long id

我还尝试通过在休眠属性中设置 hibernate.id.new_generator_mappings=true 来使用 SequenceStyleGenerator。它也不起作用。

【问题讨论】:

【参考方案1】:

如果您设置使用SequenceStyleGeneratorhibernate.id.new_generator_mappings=true,它将适用于Oracle。我们的项目中有类似的配置,效果很好。

如果你想实现批量 id 检索(比如每次 50)以加快persist/save,这里的怪癖是你需要将allocationSize 设置为 50,并将你的序列设置Increment By 设置为 50。50这里只是我选择的一个随机数,如果你有大量的坚持,你可以分配更大的数字。这里最重要的是代码中的allocationSize 和数据库中的Increment By 应该MATCH

Oracle sql 类似于

ALTER SEQUENCE YOUR_SEQUENCE_NAE INCREMENT BY 50;

JPA 实体 ID 字段如下:

        @SequenceGenerator(name = "YOUR_ID_GEN", sequenceName = "SEQ_YOUR_ID",  allocationSize=50)
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "YOUR_ID_GEN")
        @Column(name = "YOUR_ID")
        public Long getYourId() 
            return this.yourId;
        

【讨论】:

【参考方案2】:

strategy = GenerationType.AUTO 应该适用于带有标识列的 MySQL,即使您也配置了序列。在 Oracle 上运行时将使用序列生成器,但在 MySQL 上运行时将被忽略。

在您的 persistence.xml 中,您还应该在 Oracle 方言和 MySQL 方言的正确值之间切换您的 hibernate.dialect 属性。

【讨论】:

感谢您的快速回复!是的,如您所说,GenerationType.AUTO 适用于 Oracle 和 MySQL。但是对于 Oracle,它不使用 SequenceHiLoGenerator,而是使用简单的 SequenceGenerator,它将命中 Oracle DB 以查询每个新 id 上的下一个序列值。我担心这会导致性能问题。

以上是关于如何让 Hibernate 在 Oracle 上将 SequenceHiLoGenerator 用于 JPA GenerationType.AUTO?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ORACLE 上将计数作为 IF 条件传递

如何让hibernate自动生成表

Hibernate Envers审计@Embedded与throws中的基本类型无法在fetch上将字段设置为空值

hibernate和tomcat的连接池问题

如何使用java在hibernate 3 + oracle中设置查询级别超时

如何使用现有的Oracle序列在hibernate中生成id?