java - 将 JPA 实体与特定于 Hibernate 的调整分开

标签 java hibernate jpa persistence jpa-2.0

我有以下“根”实体(特定于 hibernate 的部分已注释掉):

@Entity
//@GenericGenerator(name="system-uuid",strategy="org.hibernate.id.UUIDGenerator")
public class Node extends PersistentEntity {
    private UUID id;
    private String name;
    private String displayName;

    @Id
    @GeneratedValue
    //@GeneratedValue(generator="system-uuid") //instead of above line
    //@Type(type = "pg-uuid")
    public UUID getId() { return id; }

    public String getName() { return name; }

    public String getDisplayName() { return displayName; }

    //stuff omitted
}

这是部署在 JBoss AS 6(hibernate 3.6)上的持久性上下文的一部分,数据库使用 PostgreSQL 9(使用最新的 JDBC4 驱动程序)。 PostgreSQL 有它自己的 uuid 列类型,它需要一些特定于 hibernate 的映射才能正确使用(在上面的代码中注释掉)——否则 hibernate 会尝试将 UUID 字段映射到 BINARY,那么 PostgreSQL 方言不支持 BINARY(显然是因为postgre 有 2 种存储二进制文件的方式,而 hibernate 开发人员不喜欢它)并且整个事情爆炸了。

取消注释上面的行会生成工作代码,但它迫使我对 hibernate 有编译时依赖性——我宁愿避免这种情况。

尝试将 hbm.xml 文件添加到混合中并从 persistence.xml 中引用它不会合并来自文件和注释的数据,而只是忽略注释:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="package">
    <class name="Node">
        <id name="id" type="pg-uuid">
            <generator class="org.hibernate.id.UUIDGenerator"/>
        </id>
    </class>
</hibernate-mapping>

我可以通过添加额外的 2 个属性来“弄乱”这个文件,但即使我这样做了(此时 Node 类可以工作),也可以添加任何额外的实体,例如:

@Entity
public class Host extends Node {
    //fields, getters, fluff
}

我得到以下异常:

org.hibernate.DuplicateMappingException: Duplicate class/entity mapping Node

因为 hibernate “发现”节点两次。有什么优雅的方法可以解决这个问题吗?理想情况下,Node 是唯一一个我需要特定于 hibernate 的属性的类,它将成为大型类层次结构的根。我想避免对 hibernate 的编译时依赖性或将所有内容完全映射到 hbm.xml 中。为了完整起见,这里是我使用的 persistence.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="myPU" transaction-type="JTA">
        <jta-data-source>java:/my-postgresql-DS</jta-data-source>
        <mapping-file>META-INF/hbm.xml</mapping-file>
        <!-- shouldnt need to list classes here since this is deployed -->
        <!-- in the same jar as the classes and scanning should work   -->
        <validation-mode>AUTO</validation-mode>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

最佳答案

虽然我没有回答您关于 hbm.xml 的具体问题,但我有一些建议可以简化或解决问题。

1) 您可以手动生成您的 ID。去掉 @GeneratedValue 我相信你可以只使用 Java 的 UUID.randomUUID()生成符合 RFC 4122 的 UUID,如 Hibernate 的 'uuid2' 生成器。我没有在 Hibernate 中使用过那个特定的生成器,但如果你想要的只是一个有效的 UUID,那么手动生成它似乎可以帮助你避免一些配置舞蹈。

2) 就我个人而言,我只是将 UUID(尽管是非 id 列)存储在 PostgreSQL 的 varchar 列中。我发现当需要进行数据库侦查时,我会从日志文件中剪切和粘贴 UUID,这样可以更轻松地进行查询。当 UUID 存储为 BINARY 时,这是不可能的,这就是我们将它们更改为 varchar 的原因。我们考虑过 UUID 列,但 varchar 使很多事情变得更简单并提高了互操作性。将字符串到 UUID 的转换封装在您的 Java 类中是微不足道的。

当然,出于遗留原因,您可能不得不使用 UUID 列类型,或者出于性能原因,您可能更喜欢它。至少有一个人做过 performance comparison of the two approaches .

关于java - 将 JPA 实体与特定于 Hibernate 的调整分开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4842194/

相关文章:

java - 为什么 Vaadin 11 中 VerticalLayout 内的组件不垂直对齐?

hibernate - Hibernate 的 "unsaved-value mapping was incorrect"是什么意思?

hibernate - javax.persistence/hibernate inside play

java - 使用 DashDB 作为数据库(而不是数据仓库)

java - JPA OneToMany - 删除最后一个子项时删除父项

java - 获取电子邮件客户端不支持通过 Java 发送电子邮件的 HTML 消息

java - 长按 ListView 项目时删除 ListView 项目

hibernate - Hibernate注释的Java POJO中的Grails应用程序

java - 为什么在运行 JPA 时出现此异常?

java - 如何使用 ActiveMQ Broker URI 创建双工连接?