2014-05-11 393 views
-1
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); // create session object 
     session.beginTransaction(); // start transaction object 
     session.save(user); // save the user to database 
     session.getTransaction().commit(); // commit the transaction 
     session.close(); // closing session 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     System.out.println(user.getLisOfAddresses().size()); 
    } 
} 

OUTPUT:看保健充分的输出有两个选择查询一个是用户,另一个是地址表时,我们称之为getListOfAddresses();延迟加载

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Hibernate: select lisofaddre0_.USER_ID as USER1_0_, lisofaddre0_.CITY_NAME as CITY2_0_, lisofaddre0_.PIN_CODE as PIN3_0_, lisofaddre0_.STATE_NAME as STATE4_0_, lisofaddre0_.STREET_NAME as STREET5_0_ from USER_ADDRESS lisofaddre0_ where lisofaddre0_.USER_ID=? 
2 

现在,如果你改变一些代码行该类文件以验证代理对象。 在调用getListOfAddresses()方法关闭会话之前,会发生这种情况。

  session = sessionFactory.openSession(); // again create another session object 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
      session.close(); // close the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 

现在输出:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.sdnext.hibernate.tutorial.dto.UserDetails.lisOfAddresses, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException 
(AbstractPersistentCollection.java:380) 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected 
(AbstractPersistentCollection.java:372) 
    at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119) 
    at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248) 
    at com.sdnext.hibernate.tutorial.HibernateTestDemo.main(HibernateTestDemo.java:48) 

正如上面的代码失败的运行,因为当我们使用抓取物体的延迟型战略Hibernate的Session返回代理对象,它在会话中如果我们正在关闭会话,延迟加载不会发生。

对于预先抓取:

SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); 
     session.beginTransaction(); 
     session.save(user); 
     session.getTransaction().commit(); 
     session.close(); 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     session.close(); //closing the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 
     } 
} 

OUTPUT:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_, lisofaddre1_.USER_ID as USER1_2_, lisofaddre1_.CITY_NAME as CITY2_2_, lisofaddre1_.PIN_CODE as PIN3_2_, lisofaddre1_.STATE_NAME as STATE4_2_, lisofaddre1_.STREET_NAME as STREET5_2_ from USER_DETAIL userdetail0_ left outer join USER_ADDRESS lisofaddre1_ on userdetail0_.USER_ID=lisofaddre1_.USER_ID where userdetail0_.USER_ID=? 

2 ************************* ************************************************** *** 查看此代码是否成功运行,因为我们使用EAGER获取策略,因此在此策略会话中返回原始对象,并且所有字段在加载到内存时都被初始化。 在上面的输出字符串中,完全看起来只有一个带连接子句的select语句。

我只是想知道,即使在显式关闭SESSION,

System.out.println(user.getLisOfAddresses().size()); 

执行罚款。 因此,从上述收藏处休息。来自第一级CACHE。 即使在EAGER放弃会议后(即我知道依赖的对象也加载),对象是否仍然存在?什么是懒惰负荷的情况?因为收藏品都是没有加载,难道是这个原因,

System.out.println(user.getLisOfAddresses().size()); 

显示错误在迟缓装载后会话关闭和getter被调用后关闭会话? COULS有人反映了这个? 我知道什么是懒惰和EAGER抓取?

回答

1

对一个问题的问题太多。那么,Hibernate正在做你刚才要求它做的事情。 您需要知道的getload之间的区别。当你得到的时候,Hibernate从DB获取并且反对。当你做load Hibernate制作和代理对象,并不会加载对象,直到你真的需要它(直到你打电话给它或类似的东西)。

I JUST WISH TO KNOW THAT EVEN AFTER CLOSING THE SESSION EXPLICITLY, 

System.out.println(user.getLisOfAddresses().size()); 

EXECUTES FINE. 

是它,闭幕会议不会使你的初始化(从数据库对象读取)为null,而是让这些对象detached。查看从hibernate文档中分离出来的意思。但是物体本身会一直存在,直到GC破坏它为止。

`SINCE THE COLLECTION IS NOT LOADED, IS IT THIS VERY REASON THAT 

System.out.println(user.getLisOfAddresses().size()); 

SHOWS ERROR IN LAZY LOADING AFTER SESSION IS CLOSED AND GETTER IS CALLED AFTER CLOSING THE SESSION 

这正是分离对象+延迟加载的原因。您的LisOfAddresses未加载,并且user对象已分离(表示未附加任何休眠会话)。所以它有代理,试图打数据库假设user对象连接到休眠会话这是错误的在你的情况下,失败,这是正确的。