Spring管理Session何时打开何时关闭?使用getHibernateTemplate()时如何解决nosession问题?

时间:2022-06-15 19:04:32
如题:
举例:
S2SH环境,用户表(User)和角色表(Role)是一对多双向关系映射,实体类代码如下
User.java
package com.gy.entity;

public class User {
private int userId;
private String userName;
private String password;
private String email;
private String regTime;
private Role role;

public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getRegTime() {
return regTime;
}
public void setRegTime(String regTime) {
this.regTime = regTime;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}


}

Role.java
package com.gy.entity;

import java.util.Set;

public class Role {
private int roleId;
private String roleName;
private int backstage;

private Set<User> users;

public int getRoleId() {
return roleId;
}

public void setRoleId(int roleId) {
this.roleId = roleId;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public int getBackstage() {
return backstage;
}

public void setBackstage(int backstage) {
this.backstage = backstage;
}

public Set<User> getUsers() {
return users;
}

public void setUsers(Set<User> users) {
this.users = users;
}

}

当我用User user=(User)getHibernateTemplate().get("com.gy.entity.User", userId)时可以正确查出数据,但是执行
user.getRole().getBackstage();时就会报 nosession 异常,
请问如何解决这个问题?

9 个解决方案

#1


<!-- 解决页面使用懒加载问题 -->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

#2


默认情况下,开启一个事务,就会打开session,结束一个事务后,session就会关闭,意思就是说默认情况下session是在事务中打开的。
一般的项目事务都是配置在service方法,就是运行一个service方法的时候,就会首先开启事务,然后运行该方法,然后关闭事务。

User user=(User)getHibernateTemplate().get("com.gy.entity.User", userId)
可以工作是因为这个方法在事务当中。

user.getRole().getBackstage();时就会报 nosession 异常,

是因为在事务之外,或者说你调用的地方在不在service方法中,很有可能在MVC层中,比如JSP,和 action或controller中调用,就会找不session。

如果想在是事务之外,也就是在service方法以外让session有效,可以使用楼上的filter,专门用于在事务外提供session的

#3


一楼,那个配置不懂啊

#4


引用 3 楼 huangbiao86 的回复:
一楼,那个配置不懂啊


把一楼的代码加到web.xml中,意思是加一个过滤器,是spring里边的,帮助你在默认的hibernate session关闭后,依然可以使用hibernate session

#5


我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

#6


一般都是在service里的一个方法中将你的业务逻辑写好 ,就会控制在一个事物里,但是要在页面也要进行延迟加载的话,那么最后配置OpenSessionInViewFilter,在页面加载完毕后在关闭session

#7


引用 4 楼 xiukongtiao 的回复:
引用 3 楼 huangbiao86 的回复:
一楼,那个配置不懂啊


把一楼的代码加到web.xml中,意思是加一个过滤器,是spring里边的,帮助你在默认的hibernate session关闭后,依然可以使用hibernate session

那段过滤器的配置是要加在你的struts的Filter的前面的!

#8


引用 5 楼 largegy 的回复:
我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

lazy 为false,是说你不需要延迟加载,就是在你第一次load的时候,所有数据已经被load出来了,当你在页面上使用的时候,根本不需要session,你已经有了所有的数据,所以没有任何问题,lazy为false,意思是说,除了基本类型意外的数据,在初次load的时候,并不将数据加载,以节约资源,只有需要的时候才加载,但又因为使用的时候session已经关闭,无法加载,所以需要OpenSessionInViewFilter

#9


引用 8 楼 xiukongtiao 的回复:
引用 5 楼 largegy 的回复:
我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

lazy 为false,是说你不需要延迟加载,就是在你第一次load的时候,所有数据已经被load出来了,当你在页面上使用的时候,根本不需要session,你已经有了所有的数据,所以没有任何问题……


lazy 为false 是立即检索吧 所谓立即检索是:一次查询出所有关联数据,

#1


<!-- 解决页面使用懒加载问题 -->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

#2


默认情况下,开启一个事务,就会打开session,结束一个事务后,session就会关闭,意思就是说默认情况下session是在事务中打开的。
一般的项目事务都是配置在service方法,就是运行一个service方法的时候,就会首先开启事务,然后运行该方法,然后关闭事务。

User user=(User)getHibernateTemplate().get("com.gy.entity.User", userId)
可以工作是因为这个方法在事务当中。

user.getRole().getBackstage();时就会报 nosession 异常,

是因为在事务之外,或者说你调用的地方在不在service方法中,很有可能在MVC层中,比如JSP,和 action或controller中调用,就会找不session。

如果想在是事务之外,也就是在service方法以外让session有效,可以使用楼上的filter,专门用于在事务外提供session的

#3


一楼,那个配置不懂啊

#4


引用 3 楼 huangbiao86 的回复:
一楼,那个配置不懂啊


把一楼的代码加到web.xml中,意思是加一个过滤器,是spring里边的,帮助你在默认的hibernate session关闭后,依然可以使用hibernate session

#5


我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

#6


一般都是在service里的一个方法中将你的业务逻辑写好 ,就会控制在一个事物里,但是要在页面也要进行延迟加载的话,那么最后配置OpenSessionInViewFilter,在页面加载完毕后在关闭session

#7


引用 4 楼 xiukongtiao 的回复:
引用 3 楼 huangbiao86 的回复:
一楼,那个配置不懂啊


把一楼的代码加到web.xml中,意思是加一个过滤器,是spring里边的,帮助你在默认的hibernate session关闭后,依然可以使用hibernate session

那段过滤器的配置是要加在你的struts的Filter的前面的!

#8


引用 5 楼 largegy 的回复:
我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

lazy 为false,是说你不需要延迟加载,就是在你第一次load的时候,所有数据已经被load出来了,当你在页面上使用的时候,根本不需要session,你已经有了所有的数据,所以没有任何问题,lazy为false,意思是说,除了基本类型意外的数据,在初次load的时候,并不将数据加载,以节约资源,只有需要的时候才加载,但又因为使用的时候session已经关闭,无法加载,所以需要OpenSessionInViewFilter

#9


引用 8 楼 xiukongtiao 的回复:
引用 5 楼 largegy 的回复:
我用一楼的方法还是不行,我在映射文件里把属lazy=“false” 加上就可以了。
但是为什么用OpenSessionInViewFilter不起作用呢?

lazy 为false,是说你不需要延迟加载,就是在你第一次load的时候,所有数据已经被load出来了,当你在页面上使用的时候,根本不需要session,你已经有了所有的数据,所以没有任何问题……


lazy 为false 是立即检索吧 所谓立即检索是:一次查询出所有关联数据,