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?

Author: Olvagor, 2010-05-26

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

 27
Author: Pascal Thivent,
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.

 1
Author: yatskevich,
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.

 0
Author: sammy,
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