Hibernate延迟加载 或 no session or session was closed 问题的解决(OpenSessionInViewFilter使用)
下面我是在springmvc+spring =hibernate中遇到的问题
下面是整理的项目中xml配置。大概真理了下,这是hibernate5.2和spring4.3的配置
在Hibernate配置文件中配置many-to-one 或者 one-to-many 等情况时.设置lazy="true"时 在查询对结果操作时会出现以上情况.将lazy="true" 改为 lazy="false" 可以解决问题.但那就脱离了延迟加载.
实现延迟加载的解决办法由很多.我采用了比较简单的方法:
使用:OpenSessionInViewFilter
在web.xml 添加如下代码即可:
//dao.getSessionFactory().getCurrentSession();
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
(以上代码据说stuts 2.0需要在web.xml中作为第一个filter,即所有filter的上面。位置不对可能不起作用)
如果你是通过struts配置文件中以 ContextLoaderPlugIn插件 认识spring配置文件的话,那么 OpenSessionInViewFilter 加载的spring配置文件极可能与插件加载的不是同一个对象.因为他们的key值不一样.解决办法是删除、注释掉struts配置文件中的ContextLoaderPlugIn。在web.xml中认识:
web.xml 中添加:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.cfcmms.framework.utils.SessionManage</listener-class>
</listener>
以上代码可解决:No WebApplicationContext found: no ContextLoaderListener registered异常
它回去查找默认文件名为applicationContext.xml的文件,如果你的名字不一样 需要显示配置该文件。以上工作完成后即可实现,Hibernate延迟加载。
package com.cfcmms.framework.utils;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.servlet.http.HttpSession;
import com.cfcmms.framework.bean.UserBean;
import com.cfcmms.framework.exception.ProjectException;
/**
* 系统session管理
* @author LIUM
*/
public class SessionUtils {
// Session容器 (key=session)
public static final Hashtable<String, HttpSession> SessionContext = new Hashtable<String, HttpSession>();
/**
* 用户是否在线
*/
public static boolean isOnlineUser(String userid) {
boolean result = false;
Iterator<Entry<String, HttpSession>> it = SessionContext.entrySet().iterator();
while (it.hasNext()) {
Entry<String, HttpSession> entry = it.next();
HttpSession session = entry.getValue();
try {
UserBean bean = (UserBean) session.getAttribute(Globals.SYSTEM_USER);
if (bean == null)
continue;
if (bean.getUserid().equals(userid)) {
result = true;
break;
}
} catch (IllegalStateException e) {
it.remove();
}
}
return result;
}
/**
* 注销在线用户
* @param userid 用户ID
*/
public synchronized static void invalidateOnlineUser(String userid) {
Iterator<Entry<String, HttpSession>> it = SessionContext.entrySet().iterator();
while (it.hasNext()) {
Entry<String, HttpSession> entry = it.next();
HttpSession session = entry.getValue();
try {
UserBean bean = (UserBean) session.getAttribute(Globals.SYSTEM_USER);
if (bean == null)
throw new ProjectException();
if (bean.getUserid().equals(userid)) {
invalidateOnlineUser(session);
it.remove();
}
} catch (Exception e) { // 失效用户
try {
session.invalidate();
} catch (Exception ex) {
}
it.remove();
}
}
}
/**
* 注销在线用户
* @param session 用户session
*/
public synchronized static void invalidateOnlineUser(HttpSession session) {
session.invalidate();
}
/**
* 根据用户ID获取在线用户HttpSession
* @param userid
* @return
*/
public static HttpSession getHttpSession(String userid) {
Iterator<Entry<String, HttpSession>> it = SessionContext.entrySet().iterator();
while (it.hasNext()) {
Entry<String, HttpSession> entry = it.next();
HttpSession session = entry.getValue();
try { //Globals.SYSTEM_USER系统用户存在context中的key
UserBean bean = (UserBean) session.getAttribute(Globals.SYSTEM_USER);
if (bean == null)
continue;
if (bean.getUserid().equals(userid)) {
return session;
}
} catch (IllegalStateException e) {
it.remove();
}
}
return null;
}
/**
* 根据用户ID获取在线用户UserBean
* @param userid
* @return
*/
public static UserBean getUserBean(String userid) {
Iterator<Entry<String, HttpSession>> it = SessionContext.entrySet().iterator();
while (it.hasNext()) {
Entry<String, HttpSession> entry = it.next();
HttpSession session = entry.getValue();
try {
UserBean bean = (UserBean) session.getAttribute(Globals.SYSTEM_USER);
if (bean == null)
continue;
if (bean.getUserid().equals(userid)) {
return bean;
}
} catch (IllegalStateException e) {
it.remove();
}
}
return null;
}
}