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());
}
}
输出:完全注意输出有两个选择查询,一个用于用户,另一个用于地址表,当我们调用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
现在,如果您更改此类文件的某些代码行以验证PROXY对象。 在调用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)
由于上面的代码运行失败,因为当我们使用LAZY Type策略获取对象时,hibernate会话返回代理对象,如果我们正在关闭会话,则会在会话中存在延迟加载没有发生。
渴望获取:
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());
}
}
输出:
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获取策略,因此在此策略会话中返回原始对象,并在内存加载时初始化所有字段。 在上面的输出字符串中,看起来完全只有一个带有join子句的select语句。
我只是想知道即使在会议结束后也要知道,
System.out.println(user.getLisOfAddresses().size());
执行罚款。 因此,HIBERNATE正在加载上面的收藏品。是第一级高速缓存。 在EAGER FETCHING中关闭会话之后,对象是否仍然存在(我知道相关对象也会被加载)?什么是懒惰的情况?由于收集没有加载,这是非常原因
System.out.println(user.getLisOfAddresses().size());
会议结束后是否会在会议结束时收到错误,并在闭幕后收到通知? COULS有人反思这个? 我知道什么是懒惰和EAGER FETCHING?
答案 0 :(得分:1)
关于一个问题的问题太多了。
好吧,Hibernate正在做你要求它做的事情。
您需要了解get
和load
之间的区别。当你得到,Hibernate从数据库获取并反对。当你做load
Hibernate制作和代理对象时,在你真正需要它之前不会加载对象(直到你在它上面调用getter或类似的东西)。
I JUST WISH TO KNOW THAT EVEN AFTER CLOSING THE SESSION EXPLICITLY,
System.out.println(user.getLisOfAddresses().size());
EXECUTES FINE.
是的,关闭会话不会使您的初始化(从db对象读取)为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
对象已分离(这意味着未附加任何休眠会话)。所以它有代理试图命中db假设user
对象附加到hibernate会话,这在你的情况下是错误的并且失败是正确的。