org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话,安全取消 [英] org.hibernate.LazyInitializationException: could not initialize proxy - no Session, encore un fois

查看:1083
本文介绍了org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话,安全取消的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  @ManyToMany 
private Set< User> favouritedBy;

当用户有这个时:

  @ManyToMany(mappedBy =favouritedBy)
private Set< Foo> favorites = new HashSet< Foo>();
public Set< Foo> getFavourites(){
返回最爱;





$ b

fooService具有这种功能,当会话打开时访问lazyloaded集合,通过tranactional方法:

  @Transactional(readOnly = true)
public Set< Foo> getFavourites(用户用户){
user = dao.get(User.class,user.getId()); // dao得到一个会话
Set< Foo> favorites = user.getFavourites(); //但会话不在这里,引发异常?
回报favours;
}

编辑
修正了这个问题,不使用标准:

  Set< Foo> favorites = new HashSet< Foo>(user.getFavourites()); 

,这可以通过标准来修复它。

  Session session = sessionFactory.getCurrentSession(); 
final Criteria crit = session.createCriteria(Foo.class);
crit.setFetchMode(favorites,FetchMode.JOIN);
crit.add(Property.forName(id)。eq(id));
return(Foo)crit.uniqueResult();


解决方案

默认 FetchType ManyToMany LAZY 以及使用懒惰关联明确地将这种访问称为错误。只有在会话仍处于打开状态时,才能与懒惰相关的对象进行交互。这部分文档还提供了替代方法来访问这种懒惰的对象成员。在我们的应用程序中,我们倾向于在所使用的标准中将获取模式指定为 JOIN

编辑

 设置< Foo> favorites = user.getFavourites(); 

上述语句实际上并不返回包含所有 Foo的集合对象。它只是一个代理。只有当访问集合中的元素像 favorites.iterator()等时,才会获取实际的 Foo 此操作显然发生在 getFavorites()方法之外。但是 getFavorites()方法中的 @Transactional 注释指示会话将在此方法结束时关闭。

因此,当在收藏集中调用方法时,会话已经关闭,因此是例外。为了解决这个问题,你应该使用一个Criteria对象来检索用户并指定获取类型为 JOIN so Foo对象在返回的User对象中填充。


Foo looks has this in it :

@ManyToMany
private Set<User> favouritedBy;

while user has this:

@ManyToMany(mappedBy = "favouritedBy")
private Set<Foo> favourites  = new HashSet<Foo>();
public Set<Foo> getFavourites() {
  return favourite;
}

And fooService has this, with the lazyloaded collection being accessed while session is opened, via the tranactional method :

@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;
}

EDIT This fixes it, without using criteria :

Set<Foo> favourites = new HashSet<Foo>(user.getFavourites());

and this fixes it with criteria

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();

解决方案

The default FetchType in a ManyToMany is LAZY and the hibernate documentation for working with lazy associations clearly calls out this kind of access as an error. You can interact with lazily associated objects only while the session is still open. That portion of the documentation also provides alternatives to access such lazily associated members of an object . We prefer to specify the fetch mode as JOIN in the criteria used, in our applications

Edit:

Set<Foo> favourites = user.getFavourites();

The above statement doesn't actually return a set that contains all the Foo objects. It is just a proxy. The actual Foo objects are fetched only when the elements in the set are accessed like favorites.iterator() etc., This operation is clearly happening outside your getFavorites() method. But the @Transactional annotation on the getFavorites() method indicates that the session will be closed at the end of this method.

So, when methods are called on the favourites set, the session is already closed and hence the exception.

To address this, you should use a Criteria object to retrieve the user and specify the fetch type as JOIN so that the Foo objects are populated in the User object returned.

这篇关于org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话,安全取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆