Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
571 views
in Technique[技术] by (71.8m points)

java - org.hibernate.LazyInitializationException: could not initialize proxy - no Session, encore un fois

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();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...