2009-03-21 4 views
15

J'ai 2 entités dans JPA: Entrée et Commentaire. L'entrée contient deux collections d'objets Comment.Comment avoir 2 collections du même type dans JPA?

@Entity 
public class Entry { 
    ... 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @IndexColumn(base = 1, name = "dnr") 
    private List<Comment> descriptionComments = new ArrayList<Comment>(); 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @IndexColumn(base = 1, name = "pmnr") 
    private List<Comment> postMortemComments = new ArrayList<Comment>(); 

    ... 
} 

Pour stocker ces objets, JPA + Hibernate crée la table "Entrée", "Commentaire" table et UNIQUE "Entry_Comment":

create table Entry_Comment (Entry_id integer not null, postMortemComments_id integer not null, pmnr integer not null, descriptionComments_id integer not null, dnr integer not null, primary key (Entry_id, dnr), unique (descriptionComments_id), unique (postMortemComments_id))

Stockage d'objets échouent comme descriptionComments_id et postMortemComments_id ne peut pas être "not null" en même temps.

Comment stocker un objet contenant deux collections du même type en utilisant JPA + Hibernate?

Répondre

13

C'est l'un des nombreux bogues Hibernate (HHH-3410 pour être précis).

J'ai réussi à résoudre le problème en ajoutant @JoinTable annotations à @OneToMany relations, chacune ayant son propre nom de table.

Dans votre cas, il ressemblerait à ceci:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name="entity_descriptioncomments") 
@IndexColumn(base = 1, name = "dnr") 
private List<Comment> descriptionComments = new ArrayList<Comment>(); 

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name="entity_postmortemcomments") 
@IndexColumn(base = 1, name = "pmnr") 
private List<Comment> postMortemComments = new ArrayList<Comment>(); 

Remarque: vous devez ajouter @IndexColumn annotation aussi bien (à cause de l'autre question Hibernate avec plusieurs sacs IMPATIENTS: HHH-1718/EJB-346).

+0

Et comment rendre cette relation bidirectionnelle? –

4

Pour stocker 2 collections comme celle dans JPA avec DataNucleus (http://www.datanucleus.org) vous feriez exactement comme vous avez fait. Vous n'avez pas d'annotation @JoinTable, par conséquent un FK doit être placé dans Comment pour chacune des collections. Si vous avez réellement @JoinTable quelque part (ou équivalent XML), alors le réglage des noms des tables de jointures respectives (un pour chaque collection) fonctionnerait aussi (donc ils ont leur propre table de jointure). Avoir une table de jointure partagée entre deux collections est également possible dans DataNucleus, mais ce n'est pas une JPA standard, mais plutôt une extension de fournisseur.

Comment que les cartes à Hibernate Je ne sais pas, mais c'est JPA devrait donc être cohérent depuis thats le point d'avoir une spécification ;-)

2

Il y a une faille avec la cartographie actuelle du modèle de données/point de vue du modèle de domaine: vous avez un actaully unique@OneToMany relation entre Entrée et Commentaire. Et Commentaire entité devrait avoir un attribut appelé plus de type qui prend 2 valeurs: 'Description' ou 'postmortem'.

Pour être en ligne avec votre implémentation actuelle de entrée entité que vous pouvez envisager briser Commentaire entité en 2 entités différentes (éventuellement l'utilisation des fonctions d'héritage JPA) et en utilisant @JoinTable annotation dans Entrée.

0

Si tout ce qui vous intéresse est de commander, que diriez-vous de configurer les deux définitions de colonne d'index pour avoir le même nom?

+0

J'ai essayé. Hibernate jette encore l'exception. –

Questions connexes