отделение сущностей JPA от настроек, специфичных для Hibernate - PullRequest
11 голосов
/ 30 января 2011

У меня есть следующая «корневая» сущность (закомментированные специфичные для 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 - чего я бы лучше избегал.

Попытка добавить файл 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 свойства, и он будет корнем большой иерархии классов. Я хотел бы избежать зависимости времени компиляции от гибернации или полного отображения всего в 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>

Ответы [ 3 ]

1 голос
/ 24 марта 2012

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

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

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

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

0 голосов
/ 19 марта 2013

Ответ таков: это невозможно (по крайней мере, в JPA 2.0)

0 голосов
/ 30 января 2011

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

...