Hibernate 5 ID AUTO 生成类型为 Oracle 作为序列和 MySQL 作为身份

Posted

技术标签:

【中文标题】Hibernate 5 ID AUTO 生成类型为 Oracle 作为序列和 MySQL 作为身份【英文标题】:Hibernate 5 ID AUTO Generation Type for Oracle as Sequence and MySQL as Identity 【发布时间】:2020-03-20 14:35:55 【问题描述】:

我们有一个使用 Hibernate 5 的 Java 程序,可以使用不同的数据库引擎进行安装:Oracle、PostgreSQL 或 SQL Server。现在我们正在介绍mysql

实体有一个自动生成值标识符。

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;

到目前为止,这一切都很好。 Oracle 和 PostgreSQL 安装使用 HIBERNATE_SEQUENCE 序列来生成 id 值,而 SQL Server 使用表生成的 id (IDENTITY)。

对于 MySQL,我们还想使用表生成的 id,但 MySQL 上的 Hibernate 5 GenerationType.AUTO 尝试使用 TABLE 生成器而不是 IDENTITY 生成器。

我发现 Vlad Mihalcea 的 this solution 使用本机生成器使 Hibernate 为 MySQL 选择 IDENTITY:

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
@GenericGenerator(name = "native", strategy = "native")
protected Long id;

这对 MySQL 来说很好,但是应用程序不再在 Oracle 中工作(ORA-02289:序列不存在)。 I think Hibernate 然后在 Oracle DB 中搜索一个名为 native 的序列。

是否有一种解决方案可以使所有其他数据库引擎(Oracle、PostgreSQL 和 SQL Server)的 ID 生成保持相同并为 MySQL 使用 IDENTITY?

如果不是我能看到的唯一解决方案是在 MySQL 中实现 TABLE ID 生成,但似乎not to have a good performance。

【问题讨论】:

【参考方案1】:

我几乎在问题中遇到了它,但如果有人遇到同样的情况:调用生成器 HIBERNATE_SEQUENCE 将使其与 Oracle 和 PostgreSQL 向后兼容(SQL Server 将继续使用 IDENTITY)。

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "HIBERNATE_SEQUENCE")
@GenericGenerator(name = "HIBERNATE_SEQUENCE", strategy = "native")
protected Long id;

【讨论】:

【参考方案2】:

嘿,这个问题/答案让我走上了寻找答案的道路。我正在使用带有 MSSQL SQLServer2012Dialect 和 Oracle Oracle12cDialect 的 Hibernate core 5.4.30。我还需要使用 @GenericGenerator 注释作为它的本机策略。也许我可以直接将它与@GeneratedValue 一起使用?反正...

我发现 Oracle 没有附带一个名为 HIBERNATE_SEQUENCE 的序列,即使我添加了一个,hibernate 仍然给我序列未找到错误,似乎与我的模式有关......所以你可以让事情更具体,比如这个:

    @Id
    @GenericGenerator(name = "MY_SEQUENCE", strategy = "native",
        parameters = 
            @org.hibernate.annotations.Parameter(name = "schema", value="MY_SCHEMA"),
            @org.hibernate.annotations.Parameter(name = "sequence_name", value="MY_SEQUENCE")
        
    )
    @GeneratedValue(generator = "MY_SEQUENCE")
    private Long id;

假设@GenericGenerator 的名称只需与@GeneratedValue 中的生成器名称匹配,但为了简单起见,我将其与我的实际数据库序列相同。

【讨论】:

以上是关于Hibernate 5 ID AUTO 生成类型为 Oracle 作为序列和 MySQL 作为身份的主要内容,如果未能解决你的问题,请参考以下文章

优化 Hibernate 序列 ID 生成

在使用 Hibernate 持久性提供程序的 AUTO、IDENTITY 和 TABLE(或任何其他最佳方法)中,哪种生成类型最好?

@GeneratedValue 四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.

04 主键生成策略

@OnDelete Hibernate 注解不会为 MySql 生成 ON DELETE CASCADE

hibernate.hbm2ddl.auto + Oracle 中的自定义 sql 类型