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

       在配置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过滤器的后面,网上的说法是跟循序有关,我这里就不做测试了。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值