2011-08-09 21 views
14

Tengo problemas para entender cómo Hibernate maneja los genéricos y me preguntaba cuál es la mejor manera de lograr mi objetivo.Uso de hibernación con genéricos

Dada una sencilla entidad genérica:

@Entity 
public class Box<T>{ 

    private T t;  
    @Id 
    private long id; 

    public void setT(T t) { 
     this.t = t; 
    } 

    public T getT() { 
     return t; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public long getId() { 
     return id; 
    } 
} 

Al pasar por la inicialización de hibernación, estoy consiguiendo la excepción: ...has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type

Estoy casi seguro de que esto se debe a que no le he dado una lista de hibernación restricciones de lo que <T> realmente puede ser. Sé que puede especificar cosas como targetEntity=String.class sobre t en una anotación, pero luego pierde la flexibilidad de tener genéricos. ¿Puedo limitar el alcance de lo que es un genérico aceptable usando anotaciones? Por ejemplo: ¿Qué sucede si quiero las clases ChildA, ChildB, que heredan de una clase abstracta Parent para que se puedan persistir allí. Además, también debería poder aceptar String s. ¿Puede Hibernate lidiar con tal cosa?

+2

¿Cómo espera que Hibernate para construir un objeto de este tipo genérico? Parece que tendrías que tener algún tipo de columna discriminatoria e identificar todos los posibles objetos que podrían usarse. Pero, no sé si eso es posible aquí. – Jeremy

+1

¡Eso es exactamente lo que estoy pidiendo! :) – Ryan

Respuesta

13

Lo que estamos buscando es probablemente hibernación de implicit polymorphism. También hay un little-known "any" relationship que brinda flexibilidad completa, pero tiene sus compensaciones. También puede usar un "cualquiera" en un many-to-any.

Edité: He creado un ejemplo ejecutable en Github basado en su clase "Box" y utilizando una asignación de @Any. Puede browse it (o el Box class específicamente) o verlo y ejecutarlo con

git clone git://github.com/zzantozz/testbed tmp 
cd tmp 
mvn -q compile exec:java -Dexec.mainClass=rds.hibernate.AnyMapping -pl hibernate-any 
+0

Ryan, ¿hay algún lugar en línea que tenga alguna referencia al uso de este tipo de mapeo con genéricos? Creo que he encontrado una descripción de a lo que se refiere aquí: http://v4forums.wordpress.com/2008/12/27/implicit-explicit-polymorphism-in-hibernate/ sin embargo ese ejemplo no parece satisfacer lo que Quiero hacer. ¿Estás diciendo que puedo anotar mis campos genéricos con @any (xxx) con las clases que pueden usarse? – Ryan

+0

Debería haberte dirigido a los [nuevos 3.6 documentos] (http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#mapping-types-anymapping). Tienen más detalles. Actualicé mi respuesta con ese enlace y con un ejemplo ejecutable. –

+0

Muchas gracias por pasar esto. Excelente explicación y respuesta. – Ryan

4

Ya lo hice pero con subclases.

Su clase genérica debe ser abstracta y subclases debe definir el parámetro genérico

+0

Entiendo esa parte, pero ¿qué pasa con un tipo de objeto como 'String' que no tiene nada que ver con ese árbol de herencia. ¿Es posible especificarlo adicionalmente? – Ryan

+0

lo que quiero decir es que puede especificar genérico solo si la clase que tiene una definición genérica no se guarda en la base de datos ya que hibernate no sabe qué guardar. Puede usar el campo targetEntity para especializarse en –