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.
I wrote the below code to delete a student and his books:
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:
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:
- 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= ?
- 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= ?
- Delete query to delete the books associated with the Student record. (The cascasde settings, remember)
delete from BOOK where ID= ?
- Delete query for the student
delete from STUDENT where USER_NAME= ? and STUDENT_CODE= ?
No comments:
Post a Comment