我们正在通过基于java的脚本语言groovy使用hibernate。
我们检索记录,更新记录并保存记录。
在更新期间我们清除关联,并在保存之前重新加载这些关联。
当Hibernate在删除关联之后但在建立新关联之前刷新记录时,我们会收到异常,从而触发验证失败。
即我们对关联有约束:
class Entity {
...
static constraints = {
association1(minSize:1) //require association to have at least 1 record
}
}
更新持久记录的最佳方法是什么?
一些潜在的选择:
============================================== < / p>
[1]创建新记录并复制属性:
def oldEntity = Entity.findByX(x)
if (oldEntity) {
oldEntity.properties = newEntity.properties
oldEntity.save(flush:true);|
}
else {
newEntity.save(flush:true);
}
这里的问题是这种感觉很糟糕 - 创建一个脱离的实体并通过实时复制属性。
============================================== < / p>
[2]检索记录,更新,保存,禁用刷新:
sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.MANUAL
def existingEntity = Entity.findByX(x)
existingEntity.association1.clear()
existingEntity.association2.clear()
existingEntity.association1.add(new Association(...))
existingEntity.association2.add(new Association(...))
sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.AUTO
existingEntity.save(flush:true)
不确定这种方法 - 不喜欢这种干扰Hibernate的状态管理
============================================== < / p>
[3]永久地将刷新模式设置为手动并使用save()和save(flush:true)来保存带有级联的记录:“all-delete-orphan”以确保管理关联。
这里的问题是这不是默认值 - 并依赖于我们来管理Hibernate的刷新。
============================================== < / p>
摘要:
所有这些方法似乎都闻到了 - 任何人都可以建议最不好的方法 - 甚至是这种情况下的最佳做法吗?
由于
亚历
答案 0 :(得分:1)
我们使用的解决方案是将提交模式设置为“commit”,仅使用手动entity.save(flush:true)调用进行刷新,如果不回滚则在事务结束时刷新。
Config.groovy中:
hibernate.flush.mode="commit"
我们发现,在DataSource.groovy中设置此功能并不起作用,尽管这可能是更明显的地方。此外,新线程还要求我们手动设置 - 未自动选择更改。
EntityService.groovy:
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
def sessionFactory
...
sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.parse(CH.config.hibernate.flush.mode.toUpperCase())
后一个代码似乎在线程情况下似乎是必要的,因为新线程似乎并不知道这个设置,尽管它具有其他情境感知。
答案 1 :(得分:0)
对我来说,如果你真的需要清除并重新创建这些关联,那么第二种方法就是气味较少的方法。
如果您需要操纵通过无效状态的模型,将刷新模式设置为手动没有任何问题。