2009-08-31 5 views
3

Ok, j'ai utilisé Hibernate dans plusieurs projets maintenant mais je n'ai pas appris ses subtilités avant de l'utiliser. J'ai commencé par regarder les codes qui utilisaient JPA Annotations et intégré à Spring et tout fonctionnait bien. Mais maintenant que je veux enseigner Hibernate de base à mes élèves et que je suis en train de créer un exemple et d'utiliser le tutoriel de documentation Chapitre 1, je rencontre un problème avec l'enregistrement d'un ensemble de valeurs de collection dans une classe persistante.Hibernate ne sauvegarde pas la collection de valeurs

est ici la classe persistante ...

public class Student { 
    private Long id; 
    private String firstName; 
    private String lastName; 
    private Set<Course> courses = new HashSet<Course>(); 
    private Set<String> contactDetails = new HashSet<String>(); 

    //getters and setters 
} 

Le fichier de mapping ...

<hibernate-mapping package="com.phoenixone.school.model"> 
    <class name="Student" table="student"> 
     <id name="id" column="studentId"> 
      <generator class="native" /> 
     </id> 

     <property name="firstName" /> 
     <property name="lastName" /> 

     <set name="courses" table="student_course" lazy="false"> 
      <key column="studentId" /> 
      <many-to-many column="courseId" class="Course" /> 
     </set> 

     <set name="contactDetails" table="contactDetails"> 
      <key column="studentId" /> 
      <element type="string" column="contactDetail" /> 
     </set> 
    </class> 
</hibernate-mapping> 

Le DAO (partie économie)

public class StudentDaoHibernate { 
    public void save(Student student){ 
     Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
     session.beginTransaction(); 

     session.save(student); 
     session.getTransaction().commit(); 
    } 
} 

La partie de test ...

public class TestStudentDaoHibernate { 
    public static void main(String[] args) { 
     CourseDaoHibernate courseDao = new CourseDaoHibernate(); 

     Course c1 = new Course(); 
     c1.setCourseCode("CWD"); 
     c1.setCourseName("Web Dev"); 
     courseDao.save(c1); 

     Set<Course> courses = new HashSet<Course>(); 
     courses.add(c1); 

     Student student = new Student(); 
     student.setFirstName("Bob"); 
     student.setLastName("Santos"); 
     student.setCourses(courses); 
     student.getContactDetails().add("123456789");     

       StudentDaoHibernate dao = new StudentDaoHibernate(); 
     dao.save(student); 
    } 
} 

Lorsque j'exécute ces lignes de code ...

Session session = HibernateUtil.getSessionFactory().getCurrentSession() 
session.beginTransaction(); 
Student student = (Student)session.createCriteria(Student.class) 
      .add(Restrictions.eq("id", new Long(1))).uniqueResult(); 
System.out.println("First Name: " + student.getFirstName()); 
System.out.println("Last Name: " + student.getLastName()); 

System.out.println("Courses enrolled with..."); 
for(Course c:student.getCourses()){ 
    System.out.println(c.getCourseName()); 
} 

System.out.println("Contact details..."); 
for(String s:student.getContactDetails()){ 
    System.out.println(s); 
} 

Ce que je reçois est ce ...

Prénom: Bob
Nom: Santos
Cours inscrits avec. ..
Web Dev
Coordonnées ...

Ce qui m'amène à la conclusion que la chaîne "123456789" n'a pas été enregistrée. À votre avis, quel est le problème avec mon code? Merci!

+0

3 ans et pas de réponse. J'ai ce même problème exactement ... – Stewart

Répondre

0

Je vous recommande de créer une classe Contract et de l'utiliser à la place d'une chaîne. C'est une meilleure abstraction, et la preuve qu'Hibernate a bien traité votre classe de cours suggère que cela fonctionnera bien avec Contract, aussi.

+0

Merci duffymo pour la suggestion. J'aurais fait un cours de contact aussi si je n'ai pas suivi le tutoriel. Avez-vous une idée de la raison pour laquelle elle n'a pas persisté? –

+0

Pas tout de suite, mais je vais peut-être essayer par moi-même ce soir et revenir vers vous. – duffymo

+0

Ne reviens pas duffy. Merci! –

4

Vous devez ajouter un attribut de cascade à vos éléments d'ensemble pour les cours et les détails de contact. Ceci définit quelles opérations effectuées sur l'entité parente seront appliquées à l'entité enfant. La valeur par défaut est none, ce qui explique pourquoi lorsque vous n'avez enregistré aucun des éléments enfants dans les ensembles où Student a été enregistré. Ajouter cascade = "all, delete-orphan" couvrira toutes les opérations mais vous pouvez être plus restrictif si vous le souhaitez. Voir here dans la référence Hibernate 4.3 pour plus de détails.

+0

Salut Mark! Je n'ai eu aucun problème en enregistrant le Set seulement avec le Set qui je pense parce que c'est une collection de valeurs pas une collection d'entités. J'ai ajouté cascade = "all" aux deux éléments dans le fichier de mappage comme vous l'avez suggéré. Malheureusement, j'ai toujours eu le même résultat. –

+0

Le lien est mort x_X – naXa

+0

Correction d'un lien brisé et ajout de la référence à v4.3 – Mark

1

Après session.save(student); essayer d'ajouter session.flush();

+0

J'ai résolu un problème avec l'association many-to-many qui n'a pas été correctement vidée par hibernate. – JFL

Questions connexes