Persistent collection de l'interface de l'utilisation d'Hibernate

je veux persister mon petit zoo avec Hibernate:

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

quand j'essaye de persister le zoo, Hibernate se plaint:

Use of @OneToMany or @ManyToMany targeting an unmapped class: blubb.Zoo.animals[blubb.Animal]

je sais que sur le targetEntity -@OneToMany mais cela signifierait que seuls les chiens ou les chats peuvent vivre dans mon zoo.

y a-t-il un moyen de maintenir une collection d'une interface, qui a plusieurs implémentations, avec hibernation?

28
demandé sur Olvagor 2010-05-26 16:39:07

3 réponses

les annotations JPA ne sont pas supportées sur les interfaces. À partir de Java Persistance avec Hibernate (p.210):

notez que la spécification JPA ne supporte aucune annotation de mapping sur une interface! Cela sera résolu dans une version future du Spécification; quand vous lisez ceci livre, il sera probablement possible avec des Annotations Hibernantes.

Une solution possible serait d'utiliser une Entité abstraite avec un TABLE_PER_CLASS stratégie d'héritage (parce que vous ne pouvez pas utiliser une superclasse cartographiée - qui n'est pas une entité - dans les associations). Quelque chose comme ceci:

@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>();

    ...
}

Références

27
répondu Pascal Thivent 2010-05-27 04:28:23

je peux deviner que ce que vous voulez, c'est la cartographie de l'arbre d'héritage. @L'annotation de l'héritage est la voie à suivre. Je ne sais pas s'il fonctionnera avec des interfaces, mais il fonctionnera certainement avec des classes abstraites.

1
répondu yatskevich 2010-05-26 12:50:51

je pense que vous devez annoter l'interface aussi avec @Entity et nous avons pour annoter @Transient sur tous les getters et setters d'interface.

0
répondu sammy 2011-12-31 23:13:25