在Play框架中使用ElementCollection时出现LazyInitializationException

我在我的应用程序模型集中有一个User实体,定义如下:

public class User extends Model { private String name; private byte[] sk; @Column(columnDefinition = "BINARY(272)") private byte[] pk; private int port; @OneToOne public Profile profile; @ElementCollection public List friends; @ElementCollection public List mirrors; ... } 

在我的应用程序的不同部分(控制器类)中的方法中,我正在检索并尝试修改镜像列表,如下所示:

  User u = User.connect(username); int port = ProfileFinder.getLocation(username, mirror); u.mirrors.remove(mirror); u.save(); 

这是一个错误,说明:

 LazyInitializationException occured : failed to lazily initialize a collection of role: models.User.mirrors, no session or session was closed 

我怀疑这是由于我误解了@ElementCollection标签的某些元素,但有人可以澄清我如何纠正这个问题吗?

谢谢。

默认情况下, XxxToMany关联和元素集合是延迟加载的。

这意味着只有在需要时,才会在调用其中一个集合方法时从数据库加载集合元素。 但是,当然,实体需要附加到其会话中才能实现此function。 如果会话已关闭,则会引发您获得的exception。

您可以通过设置注释的fetch属性来急切加载它,或者在返回之前使用在事务中初始化集合的查询或服务。 请注意,如果您急切地加载它,即使您不需要收集元素,它也总是会被急切地加载。

是的,你应该使用EAGER注释,但要小心,因为正如JB Nizet所说,这些元素总是会被急切地加载。

如果您不想从延迟加载更改为急切,则还有另一个选项:合并。

 User u = User.connect(username); u.merge(); 

合并将获取与会话断开连接的对象并重新连接。

例如,如果缓存对象(在本例中为User的实例),则无法在未首先在对象上使用.merge()的情况下检索用户对象的镜像。