Persist colección de interfaz usando Hibernate
Quiero persistir en mi pequeño zoo con Hibernación:
@Entity
@Table(name = "zoo")
public class Zoo {
@OneToMany
private Set<Animal> animals = new HashSet<Animal>();
}
// Just a marker interface
public interface Animal {
}
@Entity
@Table(name = "dog")
public class Dog implements Animal {
// ID and other properties
}
@Entity
@Table(name = "cat")
public class Cat implements Animal {
// ID and other properties
}
Cuando intento persistir en el zoológico, Hibernate se queja:
Use of @OneToMany or @ManyToMany targeting an unmapped class: blubb.Zoo.animals[blubb.Animal]
Conozco la propiedad targetEntity
de @OneToMany
pero eso significaría que solo Perros O gatos pueden vivir en mi zoológico.
¿Hay alguna manera de persistir una colección de una interfaz, que tiene varias implementaciones, con Hibernate?
3 answers
Las anotaciones JPA no son compatibles con las interfaces. De Java Persistence with Hibernate (p. 210):
Tenga en cuenta que la especificación JPA no admite ninguna anotación de asignación en una interfaz! Esto se resolverá en una versión futura de la especificación; cuando usted lee esto libro, probablemente será posible con Anotaciones de Hibernate.
Una posible solución sería usar una Entidad abstracta con una estrategia de herencia TABLE_PER_CLASS
(porque no se puede usar una superclase mapeada - que no es una entidad - en asociaciones). Algo como esto:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractAnimal {
@Id @GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
...
}
@Entity
public class Lion extends AbstractAnimal implements Animal {
...
}
@Entity
public class Tiger extends AbstractAnimal implements Animal {
...
}
@Entity
public class Zoo {
@Id @GeneratedValue
private Long id;
@OneToMany(targetEntity = AbstractAnimal.class)
private Set<Animal> animals = new HashSet<Animal>();
...
}
Pero no hay muchas ventajas en mantener la interfaz IMO (y en realidad, creo que las clases persistentes deben ser concretas).
Referencias
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 04:28:23
Puedo adivinar que lo que quieres es mapear el árbol de herencia. @ Anotación de herencia es el camino a seguir. No se si funcionará con interfaces, pero definitivamente funcionará con clases abstractas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-26 12:50:51
Creo que también tienes que anotar la interfaz con @Entity
y tenemos que anotar @Transient
en todos los getters y setters de la interfaz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 23:13:25