OpenSessionInView 在显示层打开session
由于hibernate存在延迟加载的问题,当dao的事物提交之后,session就关闭
此时显示层 view JSP界面需要获取延迟加载的对象EL 时候 就没办法获取对象
OpenSessionInView是解决延迟加载问题的有效方法(在view层手动的开启和关闭session 而不是
默认在事物结束之后 让hibernateTemplate自动的关闭session)
解决思路:
1 在表示层开启hibernate的session
这个session是从被sring 所管理的hibernate的sessionFactory所产生的session
当然这个session 也被对应的事物管理器使用(txManager引用了sessionFactory产生的session)
因此 事物的提交等正常使用 不同的是 事物提交后不自动 而是我们手动的在filter的view层手动关闭session
注意:!!!有一种方法是把事物加在action级别上 等待action结束之后(顺利加载对应jsp)自动关闭session
但是如果这样的话 事物的周期变得非常长 严重影响数据库的性能 因此不能这样。我们所能做的就是 事物仍然在dao或者service结束
但是session的开启和关闭放在view层 当然dao层在使用Load方法的时候 使用的不是hibernateTemplate的load
而是自己开启的session.load
2 在dao层获取表示层的session
若希望在DAO层获取表示层的数据 那么需要把数据放到threadLocal中
ThreadLocal模式主要用于解决同一线程在不同开发层次中数据共享问题
3当整个过程执行完毕之后 再关闭session
因此 需要通过filter来解决这样的问题
1 创建一个OpenSessionFilter
//一下方法来获取spring的bean工厂和Hibernate的sessionFactory
public void init(FilterConfig cfg)
throws ServletException
{
//重要
//来获取WEB中的spring的bean工厂 注意这个只需要执行一次就可以了 有一个就行
wac=WebApplicationContextUtils.getWebApplicationContext(cfg.getServletContext());
factory=(SessionFactory)wac.getBean("sessionFactory");
}
2 通过ThreadLocal来处理session
//spring的BEAN工厂 在init中获取
private static WebApplicationContext wac;
//获取beans.xml中的sessionFactory工厂
private static SessionFactory factory;
private static ThreadLocal<Session> sessionHolder=new ThreadLocal<Session>();
private static void setSession(Session session)
{
sessionHolder.set(session);
}
public static Session getSession()
{
return sessionHolder.get();
}
private static void removeSession()
{
sessionHolder.remove();
}
由于hibernate存在延迟加载的问题,当dao的事物提交之后,session就关闭
此时显示层 view JSP界面需要获取延迟加载的对象EL 时候 就没办法获取对象
OpenSessionInView是解决延迟加载问题的有效方法(在view层手动的开启和关闭session 而不是
默认在事物结束之后 让hibernateTemplate自动的关闭session)
解决思路:
1 在表示层开启hibernate的session
这个session是从被sring 所管理的hibernate的sessionFactory所产生的session
当然这个session 也被对应的事物管理器使用(txManager引用了sessionFactory产生的session)
因此 事物的提交等正常使用 不同的是 事物提交后不自动 而是我们手动的在filter的view层手动关闭session
注意:!!!有一种方法是把事物加在action级别上 等待action结束之后(顺利加载对应jsp)自动关闭session
但是如果这样的话 事物的周期变得非常长 严重影响数据库的性能 因此不能这样。我们所能做的就是 事物仍然在dao或者service结束
但是session的开启和关闭放在view层 当然dao层在使用Load方法的时候 使用的不是hibernateTemplate的load
而是自己开启的session.load
2 在dao层获取表示层的session
若希望在DAO层获取表示层的数据 那么需要把数据放到threadLocal中
ThreadLocal模式主要用于解决同一线程在不同开发层次中数据共享问题
3当整个过程执行完毕之后 再关闭session
因此 需要通过filter来解决这样的问题
1 创建一个OpenSessionFilter
//一下方法来获取spring的bean工厂和Hibernate的sessionFactory
public void init(FilterConfig cfg)
throws ServletException
{
//重要
//来获取WEB中的spring的bean工厂 注意这个只需要执行一次就可以了 有一个就行
wac=WebApplicationContextUtils.getWebApplicationContext(cfg.getServletContext());
factory=(SessionFactory)wac.getBean("sessionFactory");
}
2 通过ThreadLocal来处理session
//spring的BEAN工厂 在init中获取
private static WebApplicationContext wac;
//获取beans.xml中的sessionFactory工厂
private static SessionFactory factory;
private static ThreadLocal<Session> sessionHolder=new ThreadLocal<Session>();
private static void setSession(Session session)
{
sessionHolder.set(session);
}
public static Session getSession()
{
return sessionHolder.get();
}
private static void removeSession()
{
sessionHolder.remove();
}