In hibernate, we use session.get(Student.class, 1) to retrieve the data previously persisted. Hibernate uses proxy objects to achieve this goal, and it only gets all simple type of data immediately. It is more efficient to get collection data when needed since it may has a pretty long list of collection for the object. Therefore, the default behavior of collection retrieval is LAZY, and you can tell the framework by setting fetch = FetchType.EAGER when you want to get all collection data immediately.
Default - LAZY
session = sessionFactory.openSession(); student = null; student = (Student) session.get(Student.class, 1); session.close(); System.out.println(student.getFirstName() + " " + student.getLastName()); System.out.println(student.getParentList().size());
Output
Hibernate: select student0_.STUDENT_ID as STUDENT1_0_0_, student0_.FIRST_NAME as FIRST2_0_0_, student0_.LAST_NAME as LAST3_0_0_ from STUDENT_INFO student0_ where student0_.STUDENT_ID=? James Bond Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.mqin.hibernate.demo.Student.parentList, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186) at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:137) at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:242) at com.mqin.hibernate.demo.HibernateTest.main(HibernateTest.java:55)
String firstName and lastName is accessible since we had already initialized the value before session was closed. However, we failed to lazily initialize a collection parentList.
EAGER fetch
@ElementCollection(fetch = FetchType.EAGER) @JoinTable(name = "STUDENT_PARENTS", joinColumns = @JoinColumn(name = "STUDENT_ID")) private Collection<parent> parentList = new ArrayList<parent>();
Output
Hibernate: select student0_.STUDENT_ID as STUDENT1_0_0_, student0_.FIRST_NAME as FIRST2_0_0_, student0_.LAST_NAME as LAST3_0_0_, parentlist1_.STUDENT_ID as STUDENT1_0_2_, parentlist1_.Parent_Name as Parent2_1_2_, parentlist1_.Parent_PhoneNo as Parent3_1_2_ from STUDENT_INFO student0_ left outer join STUDENT_PARENTS parentlist1_ on student0_.STUDENT_ID=parentlist1_.STUDENT_ID where student0_.STUDENT_ID=? James Bond 2
We can get all information even after session was closed.
No comments:
Post a Comment