【问题标题】:LazyInitializationException when using ElementCollection in Play framework在 Play 框架中使用 ElementCollection 时出现 LazyInitializationException
【发布时间】:2012-05-24 17:14:13
【问题描述】:

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

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 标签的某些元素,但谁能澄清我该如何纠正这个问题?

谢谢。

【问题讨论】:

    标签: java hibernate jpa playframework


    【解决方案1】:

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

    这意味着集合元素仅在需要时才从数据库中加载,即调用其中一个集合方法。但是当然,实体需要附加到它的会话才能工作。如果会话关闭,则会抛出你得到的异常。

    您可以通过设置注释的 fetch 属性使其急切加载,或者在返回之前在事务中使用初始化集合的查询或服务。请注意,如果您将其设为预先加载,它将始终被预先加载,即使您不需要集合元素。

    【讨论】:

      【解决方案2】:

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

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

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

      例如,如果您缓存一个对象(在本例中为 User 的实例),则如果不先对对象使用 .merge(),则无法检索用户对象的镜像。

      【讨论】:

        【解决方案3】:

        类级别的用户事务

        @组件

        @Transactional

        公共类类名

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-07-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多