覆盖休眠批注

2022-09-04 23:17:37

我正在开发一个使用Hibernate并连接到Oracle实例的Java应用程序。另一个客户端希望使用相同的应用程序,但要求它在MS SQL Server上运行。我想避免对现有注释进行更改,而是创建一个xml文件包,我们可以根据环境放入这些文件。

执行此操作的一种方法是使用 JPA XML 配置来覆盖现有的类注释。但是,JPA 不支持通用生成器,由于我们遗留数据库的结构,这是一项要求。我正在研究的另一种方法是使用Hibernate XML配置来重新映射整个类并访问xml标记。但是,此解决方案存在一些问题:generator

  • 休眠不允许您有选择地覆盖实体成员
  • 休眠不允许您重新映射同一类(例如org.hibernate.AnnotationException: Use of the same entity name twice)

是否有人有过使用Hibernate XML配置文件覆盖注释的经验,或者JPA是唯一的方法吗?

使用示例进行更新

在 Oracle 中,序列用于在将新记录插入数据库时生成唯一 ID。然后,将按以下方式对 id 进行批注:

@Id
@GeneratedValue(generator="EXAMPLE_ID_GEN", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="EXAMPLE_ID_GEN", sequenceName="SEQ_EXAMPLE_ID")
@Column(name = "EXAMPLE_ID")
public String getExampleId() {
    return this.exampleId;
}

但是,MS SQL Server没有序列(意识形态差异)的概念。因此,可以使用表生成器来模拟序列。

@Id
@GeneratedValue(generator="EXAMPLE_ID_GEN", strategy=GenerationType.TABLE)
@TableGenerator(name="EXAMPLE_ID_GEN", tableName="SEQUENCE", valueColumnName="VALUE", pkColumnName="SEQUENCE", pkColumnValue="EXAMPLE_ID")
public String getExampleId() {
    return this.exampleId;
}

两种不同类型的数据库的两种不同配置。请记住,这是一个旧数据库,我们不会重写我们的应用程序来支持SQL Server标识,SQL Server的本机ID生成器(也需要不同的注释)。

为了缓解这种情况,我研究了如何使用Hibernate的,并将其指向我自己创建的一类,该类可以建模(或类似的东西),并通过扩展来自定义表的结构。@GenericGeneratororg.hibernate.id.SequenceGeneratororg.hibernate.id.TableStructure

回到我最初的问题 - 使用XML覆盖可以做到这一点吗?

我如何解决这个问题

所以,最后,我发现JPA和Hibernate没有提供我一直在寻找的开箱即用功能。相反,我创建了一个自定义生成器,用于检查数据库方言并相应地设置 TableStructure。当我探索所有选项时,我最终使用了Hibernate的注释。下面是 Id 生成注释的一个示例:@GenericGenerator

@Id
@GeneratedValue(generator="EXAMPLE_ID_GEN")
@GenericGenerator(name = "EXAMPLE_ID_GEN", strategy="com.my.package.CustomIdGenerator", parameters = {
        @Parameter(name = "parameter_name", value="parameter_value")
})
public String getExampleId() {
    return this.exampleId;
}

此解决方案需要使用新的 Id 生成器修改每个休眠实体。


答案 1

我认为,如果您在配置时不使用,注释将被省略。AnnotationConfigurationSessionFactory

因此,请使用 .Configuration


答案 2

对于生成器问题(解决方案通常是“使用本机生成器”,但由于使用旧版数据库而对您不起作用),您可以扩展 SQLServerDialect 并覆盖 getNativeIdentifierGeneratorClass 以返回一个(可能是自定义的)生成器,该生成器可以执行旧版数据库所需的操作。


推荐