2011-01-30 16 views
11

Tengo el siguiente "raíz" entidad (partes hibernar-específicos comentado out):separan entidades JPA de Hibernate específica ajustes

@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 
} 

esto es parte de un contexto de persistencia desplegado en JBoss AS 6 (hibernar 3,6) usando PostgreSQL 9 para la base de datos (usando el último controlador JDBC4). PostgreSQL tiene su propio tipo de columna uuid, que requiere algunas asignaciones específicas de hibernación para usar correctamente (comentadas en el código anterior); de lo contrario, hibernate intentará mapear el campo UUID a BINARY, entonces el dialecto PostgreSQL no admite BINARY (aparentemente porque postgre tiene 2 maneras de almacenar desarrolladores binarios y de hibernación que no les gusta) y todo explota.

al descomentar las líneas de arriba produce código de trabajo, pero me obliga a tener una dependencia de hibernación en tiempo de compilación, lo que prefiero evitar.

intentar agregar un archivo hbm.xml en la mezcla y referencia a ella desde el persistence.xml no fusionar los datos del archivo y las anotaciones, sino que simplemente hace caso omiso de las anotaciones:

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

puedo "pelusa "este archivo mediante la adición de los extra de 2 propiedades, pero incluso si lo hago (momento en el cual los trabajos de clase Node), la adición de cualesquiera entidades adicionales, como:

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

me sale la siguiente excepción:

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

ya que hibernate "encuentra" Nodo dos veces. ¿Hay alguna manera elegante alrededor de esto? idealmente, Node es la única clase para la que necesitaré propiedades específicas de hibernación, y será la raíz de una gran jerarquía de clases. Me gustaría evitar las dependencias de tiempo de compilación en hibernación o mapear todo completamente en hbm.xml. por el bien integridad, aquí está el archivo persistence.xml im usando:

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

me marcó "Java Persistence con APP" (un 2,0 APP en paquete), pero no dice nada acerca de UUID, así que supongo que aún no son compatibles con JPA. – esaj

+0

son compatibles al menos en el sentido de que todo lo que sea serializable es compatible (se traduciría en datos binarios). pero con PostgreSQL + Hibernate no obtendrá ni siquiera eso ... – radai

Respuesta

0

La respuesta es que no se puede hacer (por lo menos en JPA 2.0)

0

usted podría tratar de salir de la @Entity-anotación de la clase de nodo, y el mapa por completo en el hbm.xml, o bien cualquier elemento clases excepto Node en persistence.xml y usando < exclude-unlisted-classes />, luego correlacionándolo en hbm.xml. No se sabe si alguno de estos enfoques realmente funciona, lo último también podría evitar que hbm.xml mapee la clase.

+0

cayendo @Entity from Node da como resultado "No se ha especificado ningún identificador para [lo que se extiende Nodo]". mantener @Entity en Node mientras se intenta "reducir" la asignación (con la parte de exclusión) aún resulta en una colisión (porque sube el árbol de herencia y todavía lo encuentra, supongo) – radai

1

Tengo un par de sugerencias que pueden simplificar o solucionar el problema, aunque no estoy respondiendo su pregunta específica sobre hbm.xml.

1) Puede generar manualmente sus ID. Deje el @GeneratedValue y creo que puede usar el UUID.randomUUID() de Java para generar un UUID compatible con RFC 4122 como el generador 'uuid2' de Hibernate. No he usado ese generador específico en Hibernate, pero si lo único que quieres es un UUID válido, parece que generarlo manualmente puede ayudarte a evitar parte del baile de configuración.

2) Personalmente acabo de almacenar UUID (aunque para columnas sin id) en PostgreSQL en columnas varchar. Cuando llega el momento de investigar las bases de datos, descubro que estoy recortando y pegando los UUID de los archivos de registro, y hace que sea más fácil realizar consultas. Cuando el UUID se almacenaba como BINARIO, era imposible, por lo que los cambiamos a varchar. Consideramos columnas de UUID pero varchar hace que muchas cosas sean más simples y mejora la interoperabilidad. Es trivial encapsular la conversión String-to-UUID en su clase Java.

Por supuesto, puede que tenga que usar el tipo de columna UUID por razones heredadas, o puede preferirlo por motivos de rendimiento.Al menos una persona ha hecho un performance comparison of the two approaches.