我正在开发一个使用 Hibernate 并连接到 Oracle 实例的 Java 应用程序。另一个客户希望使用相同的应用程序,但要求它在 MS SQL Server 上运行。我想避免对现有注释进行更改,而是创建一个 xml 文件包,我们可以根据环境放入该包。
实现此目的的一种方法是使用 JPA XML 配置来覆盖现有的类注释。然而,JPA 不支持通用生成器,这是由于我们的遗留数据库的结构所必需的。我正在研究的另一种方法是使用 Hibernate XML 配置来重新映射整个类并访问generator
xml 标签。但该解决方案存在一些问题:
- Hibernate 不允许您有选择地覆盖实体成员
- Hibernate 不允许您重新映射同一类(例如
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@GenericGenerator
并将其指向我自己创建的一个类org.hibernate.id.SequenceGenerator
(或类似的东西),还可以通过扩展来自定义表的结构org.hibernate.id.TableStructure
.
回到我最初的问题 - 通过 XML 覆盖可以实现这一切吗?
我是如何解决这个问题的
所以,最后,我发现 JPA 和 Hibernate 并没有提供我正在寻找的开箱即用的功能。相反,我创建了一个自定义生成器来检查数据库方言并适当设置 TableStructure。当我探索所有选项时,我最终使用了 Hibernate@GenericGenerator
注解。这是 Id 生成注释的示例:
@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 生成器修改每个 Hibernate 实体。