Ответ 1
Ответ заключается в том, что он не может быть выполнен (по крайней мере, в JPA 2.0)
У меня есть следующий "корневой" объект (детали, зависящие от гибернации):
@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>
Ответ заключается в том, что он не может быть выполнен (по крайней мере, в JPA 2.0)
У меня есть несколько предложений, которые могут упростить или обойти проблему, хотя я не отвечаю на ваш конкретный вопрос о 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 для устаревших причин, или вы можете предпочесть его по соображениям производительности. По крайней мере, один человек сделал сравнение производительности двух подходов.
Вы можете попробовать оставить аннотацию @Entity от класса Node и полностью отобразить ее в hbm.xml или перечислить все классы, кроме Node, в файле persistence.xml и использовать < exclude-unlisted-classes/" > , а затем сопоставить его в hbm.xml. Не знаю, работает ли какой-либо из этих подходов, последний может также препятствовать отображению hbm.xml класса.