Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.coci.entity.Department.setEmp, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:138)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:138)
at com.coci.test.Test1.main(Test1.java:29)
处理懒加载用了3种方式:
1,Hibernate.initialize(代理对象)//department.getSetEmp()
这个可以,没问题
2,在配置文件中:lazy="false"
这个就出问题了,可以得到单个的数据,不能返回set集合的数据!
报错原因:lazy=“false”,的配置放错了地方。应该配置在
<set name="setEmp" cascade="save-update" lazy="false">
<key column="dept_id"></key>
<one-to-many class="Employe" />
</set>中,
而不是 <class name="Department" table="department" >中
3,web过滤器Filter (OpenSessionInView)
public class MyFilter extends HttpServlet implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getCurrentSession();
transaction = session.beginTransaction();
//执行完dofilter之后,再提交,这样就扩大了session的使用范围
chain.doFilter(request, response);
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
if(transaction != null){
transaction.rollback();
}
}finally{
HibernateUtil.closeCurrentSession();
}
}
}
用这种方法,要注意:
a,必须使用getCurrentSession(),使在一次请求中是同一个session,如果使用OpenSession(),那么回有多个session
b,关闭session的时候要注意这样关:
public static void closeCurrentSession(){
Session session = getCurrentSession();
if(session != null && session.isOpen()){
session.close();
threadLocal.set(null);
}
}
c,这样session就扩大了使用范围,在一次请求中,session都没有关闭,会话关闭延迟了