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

时间:2012-05-24 17:14:13

标签: java hibernate jpa playframework

我的模型应用程序集中有一个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<String> friends;

    @ElementCollection
        public List<String> 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标签的某些元素,但有人可以澄清我如何纠正这个问题吗?

感谢。

4 个答案:

答案 0 :(得分:8)

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果您不想从延迟加载更改为急切,则可以使用另一个选项:merge。

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

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

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

答案 3 :(得分:0)

类级别的用户交易

@Component

@Transactional

公共类className