如何解决休眠警告(HHH000470)? [英] How to fix hibernate warning (HHH000470)?

查看:243
本文介绍了如何解决休眠警告(HHH000470)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候,我收到了这个警告信息:

 
aug 09,2017 3:40:02 AM org.hibernate.collection.internal .AbstractPersistentCollection setCurrentSession
WARN:HHH000470:为集合定义了一个意外会话,但该集合未连接到该会话。持久性集合一次只能与一个会话关联。覆盖会话。收藏:[royaleserver.database.entity.PlayerEntity.homeChests#1757]

PlayerEntity:

  public class PlayerEntity implements可识别的< Long>,可序列化的{
...
@OneToMany(mappedBy =player)
private Set< ; HomeChestEntity> homeChests = new HashSet<>();

public Set< HomeChestEntity> getHomeChests(){
return homeChests;
}

public PlayerEntity setHomeChests(Set< HomeChestEntity> homeChests){
this.homeChests = homeChests;
返回此;


$ / code $ / pre

HomeChestEntity

  public class HomeChestEntity implements Serializable {
@Id
@ManyToOne
@PrimaryKeyJoinColumn(name =player_id,referencedColumnName =id )
私人PlayerEntity玩家;
...
}

在此警告消息之后,会话关闭。

 
java.lang.IllegalStateException:Session / EntityManager已关闭
at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract .java:337)
at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:135)
at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:343)
at org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:2275)
...

什么是如果你在两个线程中管理一个持久对象,通常会发生这种错误,混合从两个对象收集到的对象不同的会话,或者如果您将对象添加到瞬态对象上的集合并稍后尝试保存它(虽然可能是一个不同的信息)。



在所有情况下,都归结为不正确的会话管理。



你的问题是这样的代码: p>

  public PlayerEntity setHomeChests(Set< HomeChestEntity> homeChests){
this.homeChests = homeChests;
返回此;

$ / code>

您可能会取代关系(在 this .homeChests 字段)与属性中给定的瞬态集合。



更好的解决方案是:

  if(this.homeChests == null){
this.homeChests = new HashSet<>(homeChests);
}
else {
//非常简单,您可能更好地同步新元素...
this.homeChests.addAll(homeChests);

$ / code>

如果您不能保证元素是全新。您可能会遇到过时的对象。



正如我所说的,您需要注意会话处理涵盖树上的所有操作。不要在新会话中简单使用瞬态对象,您需要将它们合并或重新加载。我建议你仔细看看有关hibernate会话处理的stackoverflow问题。另外,hibernate文档介绍了如何使用hibernate管理会话或实体管理器的一些最佳实践。


Sometimes, i get this warn message:

aug 09, 2017 3:40:02 AM org.hibernate.collection.internal.AbstractPersistentCollection setCurrentSession
WARN: HHH000470: An unexpected session is defined for a collection, but the collection is not connected to that session. A persistent collection may only be associated with one session at a time. Overwriting session. Collection : [royaleserver.database.entity.PlayerEntity.homeChests#1757]

PlayerEntity:

public class PlayerEntity implements Identifiable<Long>, Serializable {
    ...
    @OneToMany(mappedBy = "player")
    private Set<HomeChestEntity> homeChests = new HashSet<>();  

    public Set<HomeChestEntity> getHomeChests() {
        return homeChests;
    }

    public PlayerEntity setHomeChests(Set<HomeChestEntity> homeChests) {
        this.homeChests = homeChests;
        return this;
    }
}

HomeChestEntity:

public class HomeChestEntity implements Serializable {
    @Id
    @ManyToOne
    @PrimaryKeyJoinColumn(name = "player_id", referencedColumnName = "id")
    private PlayerEntity player;
    ...
}

And after this warn message, session is closed.

java.lang.IllegalStateException: Session/EntityManager is closed
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:337)
    at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:135)
    at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:343)
    at org.hibernate.internal.SessionImpl.getPersistenceContext(SessionImpl.java:2275)
    ...

What's the problem?

解决方案

This kind of error is usually happening if you manage a persisted object in two threads, mix objects collected from two different sessions, or if you add objects to a collection on a transient object and later try to save it (could be a different message, though).

on all cases, it boils down to improper session management.

Your problem is this code:

public PlayerEntity setHomeChests(Set<HomeChestEntity> homeChests) {
    this.homeChests = homeChests;
    return this;
}

You are possibly replacing the relation (in the this.homeChests field) with the transient set given in the properties.

A better solution would be:

if(this.homeChests == null) {
    this.homeChests = new HashSet<>(homeChests);
}
else {
    // very simply, you possibly better sync the new elements in...
    this.homeChests.addAll(homeChests);
}

This solution has it's issues also, if you cannot guarantee, that the elements are all new. You may run into stale objects as well.

As I said, you need to take care that your session handling covers the all operations on the tree. Do not simply use transient objects in a new session, you need to merge them in or load them again. I suggest you carefully look at questions on stackoverflow about hibernate session handling. Also, the hibernate docs present some best practices on how to manage session or the entity manager with hibernate.

这篇关于如何解决休眠警告(HHH000470)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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