【问题标题】:Hibernate performs a Delete on a SelectHibernate 在 Select 上执行 Delete
【发布时间】:2010-02-24 08:46:00
【问题描述】:

我遇到了 Hibernate 的问题。 我目前的项目是一个小游戏。在这个游戏中,您有一个 Board,其中有许多 Fields,每个都有一个 Token
我可以毫无问题地在空数据库上进行选择,但如果我将一个对象放入其中(保存工作没有任何异常,之后数据库值看起来不错)我会遇到异常。
Board 类中有趣的部分:

@OneToMany(fetch=FetchType.EAGER)
@MapKey(name = "point")
public Map<Point, Field> getGameMatrix() {
     return gameMatrix;
}

我对获取板的查询:

return getHibernateTemplate().loadAll(Board.class);

日志现在出现了这个:

休眠:选择this_.id作为id0_2_, this_.uniqueClassName 为 uniqueCl3_0_2_, this_.borderDimension 作为borderDi4_0_2_,this_.dimension as 维度0_2_,this_.TYPE为TYPE0_2_, gamematrix2_.Board_id 作为 Board1_4_, field3_.id as gameMatrix2_4_,(选择 a11.point 来自字段 a11,其中 a11.id=gamematrix2_.gameMatrix_id) 为 公式0_4_,字段3_.id为id1_0_, field3_.point 为 point1_0_, field3_.token_id 作为 token3_1_0_, token4_.id 为 id2_1_,token4_.name 为 name2_1_, token4_.uniqueClassName 为 uniqueCl4_2_1_, token4_.TYPE 为 TYPE2_1_ from Board this_ 左外 加入 Board_Field gamematrix2_ on this_.id=gamematrix2_.Board_id 离开 外连接字段 field3_ on gamematrix2_.gameMatrix_id=field3_.id 左外连接 Token token4_ on field3_.token_id=token4_.id

直到那里看起来不错,但是 Hibernate 会执行以下操作:

Hibernate: delete from Board_Field where Board_id=?  
Hibernate: insert into Board_Field (Board_id, gameMatrix_id) values (?, ?)

我得到了这个例外:

线程“AWT-EventQueue-0”中的异常 org.springframework.dao.InvalidDataAccessApiUsageException: 对象引用了一个未保存的瞬态 instance - 保存瞬态实例 冲水前:田间;嵌套的 例外是 org.hibernate.TransientObjectException: 对象引用了一个未保存的瞬态 instance - 保存瞬态实例 冲洗前:字段

我不明白为什么它会发出删除语句。
有什么想法吗?
谢谢

【问题讨论】:

  • 之前的交易是否正常关闭?

标签: java hibernate spring jpa


【解决方案1】:

我的一个同事也有类似的问题。他现在不在,但事情与数据库完整性有关。

似乎 Hibernate 定义了比数据库更多的约束。当它加载一些数据时,Hibernate 看到数据库中的某些记录一定不存在,并试图将其删除。

尝试检查是否违反了某些应该但未定义的外键,并尝试使数据保持一致。

【讨论】:

    【解决方案2】:

    需要设置cascade属性:

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    @MapKey(name = "point")
    public Map<Point, Field> getGameMatrix() {
         return gameMatrix;
    }
    

    您还需要为 PointField 覆盖 hashCode()equals() - 让您的 IDE(Eclipse、NetBeans、IntelliJ)使用他们的业务密钥(即不是他们的自动生成的ID)

    【讨论】:

      【解决方案3】:

      在我看来,您正在将一个 Field 对象添加到 Board 类中的 Fields 集合中,但您必须首先保留新的 Field 对象(您可能是新的)

      因此出现异常消息:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例:字段

      【讨论】:

      • 我正在这样做,当我想保存一个板时,我没有得到异常。保存板工作并且数据库中的值很好。当我想选择所有板时出现异常。
      【解决方案4】:

      很久以前有一个类似的问题,虽然这个问题已经回答了,我想我会把它贴在这里以供将来参考。

      基本上,当设置器实际上为空时,我遇到了相同的行为(因为分配不存在或不正确,或者设置器中的业务逻辑导致它实际上为空)。

      Guess hibernate 首先选择并认为数据是持久的(persistence-level-cache),然后当它进行脏检查时,它发现数据已被删除(因为 getter 不会返回数据,因为它从未set) 并继续触发删除。

      也发布了in hibernate forums

      只是在这里发布以供将来参考!

      问候 拉文德拉

      【讨论】:

        猜你喜欢
        • 2012-11-02
        • 2017-09-21
        • 2014-01-03
        • 2018-04-14
        • 1970-01-01
        • 2012-12-13
        • 2012-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多