Reputation:
Okay, I've used Hibernate in several projects now but I did not learn its intricacies before using it. I started with looking at codes that used JPA Annotations and integrated with Spring and everything worked well. But now that I want to teach basic Hibernate to my students and I'm in the process of creating an example and using the documentation tutorial Chapter 1, I'm having a problem with saving a Set of collection values in one persistent class.
Here's the persistent class...
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
}
The mapping file...
<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>
The DAO (saving part)
public class StudentDaoHibernate {
public void save(Student student){
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(student);
session.getTransaction().commit();
}
}
The testing part...
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);
}
}
When I execute these lines of 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);
}
What I get is this...
First Name: Bob
Last Name: Santos
Courses enrolled with...
Web Dev
Contact details...
Which leads me to the conclusion that the String "123456789" was not saved. What do you think is the problem with my code? Thanks!
Upvotes: 5
Views: 13380
Reputation: 29119
You need to add a cascade attribute to your set elements for courses and contactDetails. This defines what operations performed on the parent entity will be applied to the child entity. The default value is none which is why when you saved the Student none of the child elements in the sets where saved.
Adding cascade="all,delete-orphan" will cover all operations but you can be more restrictive if you wish. See here in the Hibernate 4.3 reference for more details.
Upvotes: 6
Reputation: 308743
I'd recommend creating a Contract class and using that instead of a String. It's a better abstraction, and the evidence that Hibernate dealt with your Course class just fine suggests that it'll work well with Contract, too.
Upvotes: 0