Spring MVC 3.1.2 + Jackson 2:懒惰初始化集合时的LazyInitializationException - 没有关闭会话或会话 [英] Spring MVC 3.1.2 + Jackson 2: LazyInitializationException when lazily initialize a collection - no session or session was closed

查看:153
本文介绍了Spring MVC 3.1.2 + Jackson 2:懒惰初始化集合时的LazyInitializationException - 没有关闭会话或会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有以下模型Class:

我有一个使用Spring MVC 3.1.2和Jackson 2的错误。 p>

  @Entity 
@Table(name =USER)
@JsonIgnoreProperties(ignoreUnknown = true)
public class User实现Serializable
{
@Id
@SequenceGenerator(name =USER_ID,sequenceName =USER_ID_SEQ,allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =USER_ID)
私有长ID;

@Column(length = 50,nullable = false)
private String firstName;

@Column(length = 50,nullable = false)
private String lastName;
$ b @ManyToMany
@JoinTable(name =FRIENDS,
joinColumns = @JoinColumn(name =personId),
inverseJoinColumns = @JoinColumn(name = friendId)

@JsonManagedReference
private List< User>朋友;
$ b @ManyToMany
@JoinTable(name =FRIENDS,
joinColumns = @ JoinColumn(name =friendId),
inverseJoinColumns = @ JoinColumn(name = personId)

@JsonIgnore
私人列表< User> friendOf;

//其他属性和方法...
}

当我得到一个用户的单个实例时,它被Jackson正确地序列化。但是,当我尝试获取包含好友的用户实例时,会引发以下异常:


org.hibernate.LazyInitializationException :未能懒惰地初始化
a角色的集合:com.frooid.model.User.friends,无会话或
会话已关闭


我使用单个HQL获取此实例:

 从用户中选择u left join fetch u.friends f where u.id =:id 

感谢大家!

解决方案

默认情况下ToMany关联是延迟加载的。这意味着用户的朋友只会在调用 friends 列表的方法时从数据库加载。

这种延迟加载只能在用于加载用户的会话打开时发生。因此,如果您在没有加载好友列表的情况下从交易方法中返回用户,会话将被关闭,并尝试加载freinds列表将导致您遇到的异常。因此,如果客户端需要加载freinds列表,则可以使用HQL获取朋友,或者通过调用强制在服务方法内部对列表进行初始化在列表中或通过调用 Hibernate.initialize(user.getFriends())



编辑:since你在你的HQL中有一个获取,它应该工作。另一个问题是双向关联被映射两次:一次在 friends 字段中,一次在 friendOf 字段中。其中一个关联必须使用 mappedBy 属性标记为另一个关联的逆:

  @ManyToMany(mappedBy =friends)
@JsonIgnore
private List< User> friendOf;


I'm getting crazy with an error that I'm having using Spring MVC 3.1.2 and Jackson 2.

I have the following model Class:

@Entity
@Table(name = "USER")
@JsonIgnoreProperties(ignoreUnknown=true)
public class User implements Serializable
{
    @Id
    @SequenceGenerator(name = "USER_ID", sequenceName = "USER_ID_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID")
    private Long id;

    @Column(length = 50, nullable = false)
    private String firstName;

    @Column(length = 50, nullable = false)
    private String lastName;

    @ManyToMany
    @JoinTable(name = "FRIENDS",
        joinColumns = @JoinColumn(name = "personId"),
        inverseJoinColumns = @JoinColumn(name = "friendId")
    )
    @JsonManagedReference
    private List<User> friends;

    @ManyToMany
    @JoinTable(name="FRIENDS",
        joinColumns=@JoinColumn(name="friendId"),
        inverseJoinColumns=@JoinColumn(name="personId")
    )
    @JsonIgnore
    private List<User> friendOf;

    // Other attributes and methods... 
}

When I get an single instance of User it is correctly serialized by Jackson. But when I try to get an instance of User that contains friends, the following exception is thrown:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.frooid.model.User.friends, no session or session was closed

I'm getting this instance using a single HQL:

select u from User u left join fetch u.friends f where u.id = :id

Thanks to everybody!

解决方案

ToMany associations are lazy-loaded by default. This means the the friens of your users will only be loaded from the database when invoking a method of the friends list.

This lazy-loading can only occur while the session used to load the user is open. So if you return the user from your transactional method without the friends list loaded, the session will be closed, and trying to load the freinds list will lead to the exception you're getting.

So, if the client needs the freinds list to be loaded, ither fetch the friends using HQL, or force the initialization of the list, inside the service method, by calling a method on the list or by calling Hibernate.initialize(user.getFriends()).

EDIT: since you have a fetch in your HQL, it should work. Another problem is that the bidirectional association is mapped twice: once on the friends field, and once on the friendOf field. One of those association must be marked as the inverse of the other using the mappedBy attribute:

@ManyToMany(mappedBy = "friends")
@JsonIgnore
private List<User> friendOf;

这篇关于Spring MVC 3.1.2 + Jackson 2:懒惰初始化集合时的LazyInitializationException - 没有关闭会话或会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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