【问题标题】:Hibernate 5 ID AUTO Generation Type for Oracle as Sequence and MySQL as IdentityHibernate 5 ID AUTO 生成类型为 Oracle 作为序列和 MySQL 作为身份
【发布时间】: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

【问题讨论】:

    标签: java mysql oracle hibernate


    【解决方案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 中的生成器名称匹配,但为了简单起见,我将其与我的实际数据库序列相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-05
        • 2015-06-29
        • 2019-11-23
        相关资源
        最近更新 更多