Nim*_*sky 10 java spring hibernate
Foo看起来有这个:
@ManyToMany
private Set<User> favouritedBy;
Run Code Online (Sandbox Code Playgroud)
用户有这个:
@ManyToMany(mappedBy = "favouritedBy")
private Set<Foo> favourites = new HashSet<Foo>();
public Set<Foo> getFavourites() {
return favourite;
}
Run Code Online (Sandbox Code Playgroud)
并且fooService具有此功能,通过tranactional方法在会话打开时访问lazyloaded集合:
@Transactional(readOnly = true)
public Set<Foo> getFavourites(User user) {
user = dao.get(User.class, user.getId()); //the dao gets a session
Set<Foo> favourites = user.getFavourites();//but the session is not here and the exception is thrown?
return favourties;
}
Run Code Online (Sandbox Code Playgroud)
编辑 修复它,不使用条件:
Set<Foo> favourites = new HashSet<Foo>(user.getFavourites());
Run Code Online (Sandbox Code Playgroud)
这用标准修复了它
Session session = sessionFactory.getCurrentSession();
final Criteria crit = session.createCriteria(Foo.class);
crit.setFetchMode("favourites", FetchMode.JOIN);
crit.add(Property.forName("id").eq(id));
return (Foo) crit.uniqueResult();
Run Code Online (Sandbox Code Playgroud)
Vik*_*dor 10
默认FetchType
的ManyToMany
是LAZY
和Hibernate文档与懒惰协会合作明确调用这种访问是错误的.只有在会话仍处于打开状态时,您才能与延迟关联的对象进行交互.该部分文档还提供了访问对象的懒惰关联成员的替代方法.我们更喜欢JOIN
在我们的应用程序中使用的标准中指定获取模式
编辑:
Set<Foo> favourites = user.getFavourites();
Run Code Online (Sandbox Code Playgroud)
上面的语句实际上并不返回包含所有Foo
对象的集合.它只是一个代理.Foo
仅当访问集合中的元素favorites.iterator()
等时才会获取实际对象.此操作显然发生在getFavorites()
方法之外.但是该方法的@Transactional
注释getFavorites()
表明会话将在此方法结束时关闭.
因此,当在收藏夹集上调用方法时,会话已经关闭,因此异常.
要解决此问题,您应该使用Criteria对象来检索用户并指定fetch类型,JOIN
以便在返回的User对象中填充Foo对象.
小智 9
有两种解决方案.
不要使用延迟加载.
设置lazy=false
在XML或设置@OneToMany(fetch = FetchType.EAGER)
在注解.
使用延迟加载.
设置lazy=true
在XML或设置@OneToMany(fetch = FetchType.LAZY)
在注解.
并在您的.中添加过滤器 web.xml
<listener>
...
</listener>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>mySessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
...
</servlet>
Run Code Online (Sandbox Code Playgroud)并且<param-value>mySessionFactory</param-value>
是您定义的sessionFacory bean名称applicationContext.xml
归档时间: |
|
查看次数: |
38086 次 |
最近记录: |