2013-10-21 101 views
0

我尝试在Grails的服务保存对象MongoDB中:Grails的格罗姆+ MongoDB中得到

Cover saveCover = new Cover() 
saveCover.id = url 
saveCover.url = url 
saveCover.name = name 
saveCover.sku = sku 
saveCover.price = price 

saveCover.save() 

封面域看起来是这样的:

class Cover { 

    String id 
    String name 
    String url 
    String sku 
    String price 
} 

所以我想有自定义ID基于网址,但在保存过程中我得到错误:

Could not commit Datastore transaction; nested exception is org.grails.datastore.mapping.core.OptimisticLockingException: The instance was updated by another user while you were editing

但我没有使用setters,只是通过所有值在构造函数中,这个异常消失了。为什么?

回答

2

据报道在documentation这里:

Note that if you manually assign an identifier, then you will need to use the insert method instead of the save method, otherwise GORM can't work out whether you are trying to achieve an insert or an update

,所以你需要使用插入方法而不是当ID发生器是

cover.insert(failOnError: true) 

保存,如果你不这样定义的映射:

static mapping = { 
    id generator: 'assigned' 
} 

并将使用插入方法,你会得到一个自动生成的objectId:

"_id" : "5496e904e4b03b155725ebdb" 
1

当您为新模型分配一个id并尝试保存它时发生此异常,因为GORM认为它应该进行更新。

为什么当我遇到了这个问题,我用的是Grails的 - 蒙戈插件的1.3.0这个例外时

。这使用1.1.9的Grails数据存储核心代码。我注意到在847(ish) of NativeEntryEntityPersister行产生异常。此代码更新数据库中的现有域对象。

Above that on line 790是其中isUpdate被创建用于查看它是否是更新。 isInsertfalse,因为只有在插入被强制时true,并且readObjectIdentifier将返回已分配给该对象的标识,因此isUpdate将最终评估为true。

修复异常

由于&& !isInsert上线791,如果你强行插入插入代码将调用果然异常会消失。但是,当我这样做时,分配的ID没有保存,而是使用了生成的对象ID。我看到这个问题的解决方案在line 803,它检查发生器是否设置为"assigned"

要解决您可以添加以下映射。

class Cover { 
    String id 
    String name 
    String url 
    String sku 
    String price 
    static mapping = { 
     id generator: 'assigned' 
    } 
} 

这样做的副作用是,你永远需要分配新盖的域对象的ID。

+0

我不明白GORM默认为什么这么认为。你能解释一下吗? – sphinks

+0

我已经更新了关于为什么gorm认为这个更详细的问题。 – PaddyDwyer