Разделение сущностей JPA от настроек, зависящих от 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 попытается сопоставить поле UUID с BINARY, тогда диалект PostgreSQL не поддерживает BINARY (видимо, потому что postgre имеет 2 способа хранения двоичных и 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 дважды. есть ли какой-нибудь элегантный способ обойти это? В идеале Node является единственным классом, для которого мне понадобятся свойства, связанные с гибернацией, и это будет корень большой иерархии классов. я бы хотел избежать любых зависимостей времени компиляции от спящего режима или полностью отобразить все в hbm.xml. для полноты, здесь файл persistence.xml im, используя:

<?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>

Ответ 1

Ответ заключается в том, что он не может быть выполнен (по крайней мере, в JPA 2.0)

Ответ 2

У меня есть несколько предложений, которые могут упростить или обойти проблему, хотя я не отвечаю на ваш конкретный вопрос о hbm.xml.

1) Вы можете вручную генерировать свои идентификаторы. Оставьте значение @GeneratedValue, и я считаю, что вы можете просто использовать Java UUID.randomUUID() для генерации RFC 4122-совместимого UUID, такого как Hibernate 'uuid2'. Я не использовал этот конкретный генератор в Hibernate, но если все, что вы хотите, является допустимым UUID, кажется, что оно создается вручную, это может помочь вам избежать некоторых настроек танец.

2) Лично я просто храню UUID (хотя и для столбцов без id) в PostgreSQL в столбцах varchar. Я нахожу, когда приходит время для отслеживания базы данных, я вырезаю и вставляю UUID из файлов журналов, и это упрощает запрос. Когда UUID был сохранен как BINARY, это было невозможно, поэтому мы изменили их на varchar. Мы рассмотрели столбцы UUID, но varchar упрощает и упрощает взаимодействие. Это тривиально, чтобы инкапсулировать преобразование String-to-UUID в ваш Java-класс.

Конечно, вам может понадобиться использовать тип столбца UUID для устаревших причин, или вы можете предпочесть его по соображениям производительности. По крайней мере, один человек сделал сравнение производительности двух подходов.

Ответ 3

Вы можете попробовать оставить аннотацию @Entity от класса Node и полностью отобразить ее в hbm.xml или перечислить все классы, кроме Node, в файле persistence.xml и использовать < exclude-unlisted-classes/" > , а затем сопоставить его в hbm.xml. Не знаю, работает ли какой-либо из этих подходов, последний может также препятствовать отображению hbm.xml класса.