2011-03-23 7 views
0

J'essaie d'implémenter mon modèle en utilisant les annotations d'hibernation. J'ai 3 classes, l'image, la personne, et les étiquettes. Tags est une table composée de 4 champs, un id, personId, imageId, et un createdDate. Personne a le champs nom, id, date de naissance, etc. Ma classe d'image est définie comme suit:Hibernate Annotations avec une collection

@Entity 
@Table(name="Image") 
public class Image { 
    private Integer imageId; 
    private Set<Person> persons = new HashSet<Person>(); 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID") 
    public Integer getImageId() { 
     return imageId; 
    } 

    public void setImageId(Integer imageId) { 
     this.imageId = imageId; 
    } 

    @ManyToMany 
    @JoinTable(name="Tags", 
       joinColumns = {@JoinColumn(name="imageId", nullable=false)}, 
       inverseJoinColumns = {@JoinColumn(name="personId", nullable=false)}) 
    public Set<Person> getPersons() { 
     return persons; 
    } 

    public void setPersons(Set<Person> persons) { 
     this.persons = persons; 
    } 

Si je supprime les annotations sur la méthode getPersons() je peux utiliser les classes et ajouter et supprimer des enregistrements. Je veux aller chercher toutes les étiquettes avec l'image et j'essaye d'utiliser un ensemble. Je continue à obtenir l'erreur suivante:

org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: com.exmaple.persons, no session or session was closed 

Quelqu'un peut-il me aider et s'il vous plaît laissez-moi savoir ce que je fais mal?

Merci

Répondre

5

Ce message d'erreur - qui n'a en fait rien à voir avec votre stratégie de mapping d'association ou annotations - signifie que vous avez tenté d'accéder à une collection lazy-chargé sur un de vos objets de domaine après la Session était fermé.

La solution consiste à désactiver chargement paresseux pour cette collection, charger explicitement la collection avant la Session est fermé (par exemple, en appelant foo.getBars().size()), ou en vous assurant que les Session reste ouvert jusqu'à ce qu'il ne soit plus nécessaire.

Si vous n'êtes pas sûr de chargement paresseux est, here is the section in the Hibernate manual.

+0

Im va accepter cette réponse. J'apprécie l'aide. Je lis encore les chapitres 10 et 13 dans la documentation du printemps. Je posterai des mises à jour quand j'aurai une chance. – blong824

0

Merci pour la réponse matt. Je suis confus maintenant. Ma requête pour récupérer l'image ressemble à ceci:

public Image findByImageId(Integer imageId) { 
    @SuppressWarnings("unchecked") 
    List<Image> images = hibernateTemplate.find(
      "from Image where imageId=?", imageId); 
    return (Image)images.get(0); 
} 

Je pensais que je peux appeler la seule requête HQL et si mes correspondances sont correctes, il ramènerai les données associées.

Je regardais cet exemple à ce lien hibernate mappings:

2.2.5.3.1.3. Unidirectional with join table 
A unidirectional one to many with join table is much preferred. This association is described through an @JoinTable. 

@Entity 
public class Trainer { 
    @OneToMany 
    @JoinTable(
      name="TrainedMonkeys", 
      joinColumns = @JoinColumn(name="trainer_id"), 
      inverseJoinColumns = @JoinColumn(name="monkey_id") 
    ) 
    public Set<Monkey> getTrainedMonkeys() { 
    ... 
} 

@Entity 
public class Monkey { 
    ... //no bidir 
}   Trainer describes a unidirectional relationship with Monkey using the join table TrainedMonkeys, with a foreign key trainer_id to Trainer (joinColumns) and a foreign key monkey_id to Monkey (inversejoinColumns). 
+0

Est-ce que quelqu'un a d'autres commentaires sur ma question de suivi? Merci – blong824

+0

Je ne suis pas sûr si je comprends ce que vous demandez ici, mais votre requête pour renvoyer la première instance 'Image' retournerait en fait l'objet - mais Hibernate est paresseux en chargeant la collection' Image.trainers', dont l'erreur message se réfère à. C'est la collection que vous devez charger avant de fermer la session, ou marquer comme non-paresseux. –

+0

Je pense que c'est là que je suis confus. Donc, ma requête saisit l'objet image qui a un ensemble qui est paresseux chargé. Donc, c'est fondamentalement un ensemble vide quand je demande un objet image spécifique? Je crois depuis que j'utilise hibernateTemplate que les sessions sont traitées pour moi. Donc, quand je fais un hibernate.find ("à partir d'Image ...), je dois faire une autre recherche pour les objets de la personne et peupler cet ensemble? – blong824

Questions connexes