【问题标题】:Saving/updating object with hibernate使用休眠保存/更新对象
【发布时间】:2012-08-09 17:17:02
【问题描述】:

我的班级 Foo 有方法:

 protected void saveMany(Collection<T> many) {  
    for(Object one : many) {
            one = session.merge(one); // also tried this commented out
            session.saveOrUpdate(one); // session.merge(one);   
        }

尝试使用 saveOrUpdate 并合并,但都给了我这个异常:

Error: Invocation of method 'saveMany' in class Foo threw exception class org.hibernate.HibernateException : org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [Bar#581301]

如何解决这个问题?

旁注:

当我截断我的表时,保存部分可以工作,但是当我填充表并再次运行此方法时,更新表时,它会失败,但出现此异常

【问题讨论】:

  • 当您调用 merge() 时,您是否记得在实例 返回 从 merge() 而不是您传递给 merge() 的实例上调用 saveOrUpdate()范围?见my answer here
  • @Brad :不,我根本没有调用 saveOrUpdate,我只是调用了合并。你的意思是这样的? session.saveOrUpdate(session.merge(one)),上面写着:The left-hand side of an assignment must be a variable
  • @Brad:我这样做了:one = session.merge(one); session.saveOrUpdate(one);
  • @invariant 好的,我想我找到了发生这种情况的地方,但是我怎样才能让对象的第一个实例脱离休眠上下文?

标签: java hibernate generics


【解决方案1】:

如果您有一个带有@Id 的类的分离实例已经存在于 Hibernate 会话缓存中,那么您必须调用 merge() 将分离实例合并到缓存中。那你应该打电话给saveOrUpdate()。

但您必须小心地保存从调用 merge() 中返回的实例返回,而不是您作为参数传入的实例。所以你的代码必须是这样的

mergedOne = session.merge(one);
session.saveOrUpdate(mergedOne);

如果您在事务内部进行操作,则数据库将在会话结束并且事务提交之前不会更新,或者您显式调用 flush()

【讨论】:

    【解决方案2】:

    它表示您正在尝试保存一个新对象,其 Id 已被另一个对象使用。

    您可能没有正确实现equals 和hashCode。所以,hibernate发现你想用id1保存Object2,而数据库里有id1的Object2,却没有Object2.equals(Object1)

    【讨论】:

    • 也许吧,但这就是我想要做的:当数据库中存在具有相同主键的对象时,只需覆盖字段。
    • 但是你的对象实现了equals()吗?即使它只是 id 的等价物。在关于 JPA(好吧,不是 Hibernate)的课程中,有人告诉我,您必须正确实现 equals 才能使其工作。
    • 不,它没有,你能给我一个关于你的意思的链接吗?我没有等于无处可去。
    • 哇,这真是令人困惑,我真的不明白,当我得到主键时,为什么我必须制作另一个标识符。
    【解决方案3】:

    您可能正在尝试保存具有一个或多个 equals 对象的 List&lt;T&gt;。

    使用 SaveOrUpdate 或合并来解决它,或者简单地尝试使所有对象唯一。

    【讨论】:

    • 不,我没有列表,我有对象T。我尝试使用最初帖子中看到的合并和 saveOrUpdate。
    • 您正在传递 Collection 并且 List 扩展 Collection 因此您的 Collection 有重复项。尝试删除这些重复项。
    • 可能是我的实际方法有 2 个这样的参数集合的问题:saveMany(Collection&lt;T&gt; update, Collection&lt;T&gt; delete)。我从初始代码中删除了一个以简化事情。
    【解决方案4】:

    您的 Hibernatesession 缓存中有多个版本的“one”!

    您必须找到“one”的实例并使用“.evict(...)”从 Hibernatesessions 中删除缓存信息。

    终于可以成功调用 saveOrUpdate 了!

    【讨论】:

    • 我想我正在这样做,但我关闭了我的最后一个会话。
    • 关闭!= 驱逐。还是给出了“一”和闭会的参考! System.out.println(one.getClass()) 是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 2014-06-10
    • 2011-11-06
    • 2015-04-27
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多