【发布时间】:2012-09-30 07:14:48
【问题描述】:
可能重复:
Hibernate: different object with the same identifier value was already associated with the session
我在 Grails 中的控制器中有以下代码失败并显示 "a different object with the same identifier value was already associated with the session" 错误消息。
我已经访问了几个页面,上面说我必须在调用 save 之前调用 "merge" 最终出现此错误 Provided id of the wrong type for class com.easytha.QuizTag. Expected: class java.lang.Long, got class org.hibernate.action.DelayedPostInsertIdentifier
有人建议 grails 可搜索插件可能会导致此问题,我应该从我的域类中删除 searchable = true ,这不是一个选项(请参阅上一篇文章grails searcheable plugin search in inner hasMany class)
需要指出的一点是,在调用 q.save() 时不会抛出错误,而是在调用 redirect redirect(action:"show",id:id) 时抛出错误!!
有什么建议吗?
def addTags(String tags,Long id){
if(tags){
String[] strTags = tags.split(",");
Quiz q = Quiz.get(id)
for(String t in strTags){
Tag tagToAdd = Tag.findByTag(t)
if(!tagToAdd){
tagToAdd = new Tag(tag:t)
tagToAdd.save()
}
println "---> "+tagToAdd +" Quiz"+q?.id
def qt = QuizTag.findByQuizAndTag(q,tagToAdd)
if(!qt){
qt = new QuizTag(quiz:q,tag:tagToAdd);
q.addToTags(qt)
}
}
q.save()
redirect(action:"show",id:id)
}
}
-----------编辑---------------
Final code that worked with searchable plugin
def addTags(String tags,Long id){
if(tags){
String[] strTags = tags.split(",");
Quiz q = Quiz.get(id)
for(String t in strTags){
if (q.tags.any { QuizTag qt -> qt.tag.tag == t }) { continue; }
Tag tagToAdd = Tag.findOrSaveByTag(t);
QuizTag qt = new QuizTag(quiz:q,tag:tagToAdd)
q.addToTags(qt)
}
q.save(flush:true)
redirect(action:"show",id:id)
}
}
【问题讨论】:
-
来自 save() 方法的描述:“除非使用flush参数,否则对象不会立即持久化。”这就是为什么只有在请求完成时才会出现错误。
-
@TiagoFarias 你是对的。在调用 q.save(flush:true) 之后,我在该行得到了错误,这里要注意的另一件事是,即使在错误之后我的数据仍然被保存!此外,仅当标签已经存在时才会发生此错误,这意味着“Tag.findByTag(t)”返回了一些东西
-
我无法发布答案,但请看:保存前检查
q.hasChanged()。
标签: hibernate grails groovy grails-searchable