I have a question days ago on how to configure the student course relations. The main concern is how to express the score attribute. Finally, I find the following solution. To Configure it as a
one-to-many map
. The
key is the
course entity, and the
value is the
score(simple element).
I finally got the following solution:
In the new way, the above code is easy to write and read, as it is very natual to do so. And also the disadvantage is that we can not config a reverse relation to let a course associate to a student set, as hibernate didn't support that.
I finally got the following solution:
public class Student implements java.io.Serializable {
// Fields
private String id;
private Clazz clazz;
private String studentName;
private Integer studentAge;
private Map courseScoreMap = new HashMap(0);
... omit the setters and getters
}
public class Course implements java.io.Serializable {
// Fields
private String id;
private String courseName;
// omit the setters and getters
}
public class Clazz implements java.io.Serializable {
// Fields
private String id;
private String clazzName;
private Set students = new HashSet(0);
// omit the setters and getters
}
The following is the HBM file:
<hibernate-mapping package="com.hipposoft.school.domain">
<class name="Clazz" table="clazz">
<id name="id" type="string">
<column name="id" length="32">
<generator class="uuid.hex"></generator>
</column>
<property name="clazzName" type="string">
<column name="clazz_name" length="100">
</column>
<set name="students" inverse="true" cascade="all">
<key>
<column name="clazz_id" length="32" not-null="true">
</column>
<one-to-many class="Student">
</one-to-many>
</key>
</set>
<hibernate-mapping package="com.hipposoft.school.domain">
<class name="Course" table="course">
<id name="id" type="string">
<column name="id" length="32">
<generator class="uuid.hex"></generator>
</column>
<property name="courseName" type="string">
<column name="course_name" length="100">
</column>
</property>
</id>
<hibernate-mapping package="com.hipposoft.school.domain">
<class name="Student" table="student">
<id name="id" type="string">
<column name="id" length="32">
<generator class="uuid.hex"></generator>
</column>
<many-to-one name="clazz" class="Clazz" fetch="select">
<column name="clazz_id" length="32" not-null="true">
</column>
<property name="studentName" type="string">
<column name="student_name" length="100" not-null="true">
</column>
<property name="studentAge" type="integer">
<column name="student_age">
</column>
<map name="courseScoreMap" cascade="all-delete-orphan" table="student_course_select">
<key column="student_id"/>
<map-key-many-to-many class="Course" column="course_id"/>
<element type="double" column="score" />
</map>
</class>
</hibernate-mapping>
The following is the test code:
public void testMap() throws Exception{
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();
Clazz clazz = new Clazz();
clazz.setClazzName("Gao San");
Student s = new Student(clazz,"James");
clazz.getStudents().add(s);
// save the student and the class
session.save(clazz);
Course course = new Course("语文");
session.save(course);
session.flush();
s.getCourseScoreMap().put(course, new Double(80.5));
// save the course score
session.update(s);
session.getTransaction().commit();
}
In the new way, the above code is easy to write and read, as it is very natual to do so. And also the disadvantage is that we can not config a reverse relation to let a course associate to a student set, as hibernate didn't support that.