Search This Blog

Sunday 1 January 2012

Compisite Identifiers And Associations-2

Continuing from the previous post, if Student were to have a many-to-one association with Books, then the foreign-key(user_name) would also be present in this association.
public class Student implements Serializable {
    private String studentCode;
    private User user;
    private Set<Book> books = new HashSet<Book>();
//setter-getters
}
public class Book {
    private Integer id;
    private String name;
    private Student student;
//setter-getters
}
The above classes look same as all the earlier examples. However the difference is visible when we look into the hibernate mappings:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ec.composite_primary.merged">
    <class name="Student" table="STUDENT">
        <composite-id>
            <key-many-to-one name="user" column="USER_NAME" />
            <key-property name="studentCode" column="STUDENT_CODE" />
        </composite-id>

        <set name="books" cascade="all" inverse="true">
            <key>
                <column name="USER_NAME" />
                <column name="STUDENT_CODE" />
            </key>
            <one-to-many class="Book" />
        </set>
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ec.composite_primary.merged">
    <class name="Book" table="BOOK">
        <id name="id" type="integer" column="ID">
            <generator class="assigned" />
        </id>
        <property name="name" column="NAME" />
        <many-to-one name="student" class="Student">
            <column name="USER_NAME" />
            <column name="STUDENT_CODE" />
        </many-to-one>
    </class>
</hibernate-mapping>
As can be seen both columns need to specified for the relation to work.Also the order of the columns is very important. At all places in associations the order must be same as order of columns in the identifier definition. On executing the code to add books and students:
static void testCreate() {
    User user = new User();
    user.setName("Ronald");
    user.setAge(14);

    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();
    session.save(user);//saving the user
        
    Student student = new Student();
    student.setUser(user);//linking the user and student
    student.setStudentCode("#2145");
        
    //adding books to the student
    Book book1 = new Book();
    book1.setId(1);
    book1.setName("Going Nuts !!");
    book1.setStudent(student);//inverse at play
    student.getBooks().add(book1);        
    session.save(student);//saving the student and cascade-saving the books
    t.commit();
}
A snapshot of the db indicates that the records were inserted successfully:
records in the database
I wrote the below code to delete a student and his books:
static void deleteElements() {
    Session session = sessionFactory.openSession();
    Transaction t = session.beginTransaction();
    User user = (User) session.load(User.class, "Ronald");
    Student student = new Student();
    student.setStudentCode("#2145");
    student.setUser(user);
    student = (Student) session.load(Student.class, student);
    session.delete(student);
    t.commit();
    session.close();
}
The queries fired were:
  1. Select query to load the student record (I am not sure yet why)
    select
            student0_.USER_NAME as USER1_2_0_,
            student0_.STUDENT_CODE as STUDENT2_2_0_ 
        from
            STUDENT student0_ 
        where
            student0_.USER_NAME= ? 
            and student0_.STUDENT_CODE= ?
    
  2. Select query to load the books associate with the student record (I am not sure yet why)
    select
            books0_.USER_NAME as USER3_1_,
            books0_.STUDENT_CODE as STUDENT4_1_,
            books0_.ID as ID1_,
            books0_.ID as ID1_0_,
            books0_.NAME as NAME1_0_,
            books0_.USER_NAME as USER3_1_0_,
            books0_.STUDENT_CODE as STUDENT4_1_0_ 
        from
            BOOK books0_ 
        where
            books0_.USER_NAME= ? 
            and books0_.STUDENT_CODE= ?
    
  3. Delete query to delete the books associated with the Student record. (The cascasde settings, remember)
    delete 
        from
            BOOK 
        where
            ID= ?
    
  4. Delete query for the student
    delete 
        from
            STUDENT 
        where
            USER_NAME= ? 
            and STUDENT_CODE= ?
    

No comments:

Post a Comment