【问题标题】:Grails throws NonUniqueObjectException when findWhere called调用 findWhere 时 Grails 抛出 NonUniqueObjectException
【发布时间】:2012-07-02 23:35:19
【问题描述】:

我正在构建一个 grails 应用程序,其中包含分配了 id 生成器的域类(也就是说,它们不会自动生成)。假设我有一个域类 Parent,static hasMany = [children: Child] 和域类 Child。

我正在尝试使用 Parent.findWhere(propertyMap) 定位 Parent 的实例,但收到 NonUniqueObjectException 指示已经有一个与此会话关联的 Child 实例,其 ID 为 0。我的 propertyMap 不包含id 的条目。

现在,当我尝试在会话中保存一个类的两个实例而不设置它们的 id 时,我习惯于得到这个错误。因为 id 不是自动生成的,所以它们默认为零,这允许保存第一个,第二个抛出错误,因为 id 是第一个的副本。令我惊讶的是,我试图找到一个实例,而不是保存一个实例......有谁知道可能导致这种行为的原因以及我如何在仍然使用我的属性映射进行搜索的同时绕过它?

【问题讨论】:

  • 试试“findAllWhere”看看它会返回什么。
  • 相同。我有一种感觉 findAllWherefindWhere 要么相互依赖,要么具有相同的实现,除了返回的结果数量......

标签: hibernate grails orm grails-orm


【解决方案1】:

事实证明,这是一个时髦的语法糖问题。我在打电话 findWhere 就像

Parent.findWhere([ firstProperty: "firstValue", secondProperty: "SecondValue" ])

但显然我应该使用

Parent.findWhere( firstProperty: "firstValue", secondProperty: "SecondValue" )

(注意没有方括号)。我不知道为什么这会有所作为,但 findWhere 现在按预期工作。任何可能知道它为什么会这样表现的人都会加分。

【讨论】:

    【解决方案2】:

    嗯,Hibernate 有一个严格的限制,即不能有 2 个对象在会话中表示相同的 id,如您所知。您可能没有注意到的是,无论是在save() 操作还是更新甚至是动态查询中:如果在同一个 Hibernate Session 中有 2 个具有相同 id 的对象,Hibernate 都会引发这样的异常一。确保在您的会话中有另一个与该对象类似的对象。

    Here 它说:

    如果您使用 GORM 以任何方式检索域实例,例如 通过 get() 方法或任何类型的查询,则对象是 自动与会话关联。

    在会话中可能有一个子对象引用父对象(还没有 id)。除了在您的父对象进入会话之前提供父对象 ID 或避免将引用父对象的子对象保存到会话之外,我没有看到其他优雅的方法。其他方法是在您的对象上使用evict(),例如:session.evict(object)。但这不是一件好事。

    干杯!

    【讨论】:

    • 问题是,findWnere 根本不应该创建一个对象,它应该找到一个已经存在的对象。如果没有创建新的 id,这怎么会导致 id 冲突?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    相关资源
    最近更新 更多