使用struts2+spring+hibernate测试多对多关系映射的时候出现懒加载问题:could not initialize proxy - no Session

来源:互联网 发布:c一维数组排序算法 编辑:程序博客网 时间:2024/05/29 14:26

       在配置struts2+hibernate+spring的时候,我这里出现了这么一个问题,使用hibernate配置多对多的映射关系的时候,使用懒加载模式的话会出现这么一个错误:

Caused by:org.hibernate.LazyInitializationException: failed to lazily initialize acollection of role: domain.Department.menberList, could not initialize proxy -no Session

我的是用户与部门之间的多对多的映射关系,相关代码如下:

@ManyToMany(mappedBy = "menberList", cascade = CascadeType.MERGE)public Set<Department> getDepartments() {    return departments;}

@ManyToMany(cascade = CascadeType.MERGE)@JoinTable(        name = "department_person",        joinColumns = @JoinColumn(name = "department_id"),        inverseJoinColumns = @JoinColumn(name = "person_id"))public Set<Person> getMenberList() {    return menberList;}

如代码所示,我没有将懒加载模式设置为false,因为我觉得这样做的话会严重影响系统的性能,当然赶项目的同学可以将懒加载模式设置为false,方法就是在@ManyToMany注解中添加一个fetch = FetchType.EAGER,注意是两边都要加。这样就不会有什么问题,但是会严重影响系统性能。比如我们查询部门的信息,但是系统连带部门里面的员工全部的信息都查出来了,这大多数时候是不需要的。

好吧,回到最开始的问题,出现了这么一个exception,这么解决呢?

在度娘上面找了好久,发现基本都是同一个回答:

在web.xml里面加上下面这么这个过滤器:

<filter><filter-name>openSessionInView</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class></filter><filter-mapping><filter-name>openSessionInView</filter-name><url-pattern>/*</url-pattern></filter-mapping>

好吧,小编一样照抄了进去,发现有出现了一个新的问题,

No WebApplicationContext found: noContextLoaderListener registered?

好吧,相信大家已经麻木了,在问题解决之前又出现更多的问题。

小编又到度娘上面找,大多数都说解决办法是声明ContextLoaderListener 这个监听器,在web.xml里面配置如下:

<listener><listener-class>com.j.chat.upgrade.web.core.SystemLaunchListener</listener-class></listener><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-config.xml</param-value></context-param>

       小编配置了之后又出现了一个问题……反正就是打不开了。。。

       最后小编自己想了好几天,发现这么做就可以。小编是个编程菜鸟,在获取Session的时候一律采用getCurrentSession()的方式,现在才发现是不行的,当我们需要用到懒加载的时候使用openSession()获取Session就可以正常运行。当我们添加、删除、修改的时候可以使用getCurrentSession,但是当我们查询的时候如果有多对多的映射关系的话就应该使用openSession(),这样的话我们在使用懒加载的时候才不会出现Session has close的情况。

       刚才我们使用openSession新建了一个回话,但是我们并不能关闭它,马上关闭的话懒加载就不能实现了。好吧,那我们不关闭它,可是后来我执行了一条update语句。出现了下面这个错误

Illegal attempt to associate a collection with two open sessions

这个错误的意思大概是有两个session引用了同一个collection对象,后来我的解决办法是修改dao层的update代码:

如下:

public void update(T entity) {        Session session = getSessionFactory().openSession();        Transaction transaction =session.beginTransaction();        session.update(session.merge(entity));        transaction.commit();    }

有兴趣的同学可以百度一下session.merge,由于我也是个菜鸟,这里就不做解释了。

在web.xml里面加上了如下代码:

<filter>        <filter-name>opensession</filter-name>        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>        <init-param>            <param-name>singleSession</param-name>            <param-value>true</param-value>        </init-param>    </filter>    <filter-mapping>        <filter-name>opensession</filter-name>        <url-pattern>*</url-pattern>    </filter-mapping>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:applicationContext.xml</param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>
注意这个代码放在struts2过滤器的后面,网上的说法是跟循序有关,我这里就不做测试了。





0 0