Hibernate 休眠更新持久记录
我们通过基于java的脚本语言groovy使用hibernate 我们检索记录、更新记录并保存记录 在更新过程中,我们清除关联,并在保存之前重新加载这些关联 当Hibernate在删除关联之后但在建立新关联之前刷新记录时,会出现异常,从而触发验证失败 也就是说,我们对关联有限制:Hibernate 休眠更新持久记录,hibernate,validation,Hibernate,Validation,我们通过基于java的脚本语言groovy使用hibernate 我们检索记录、更新记录并保存记录 在更新过程中,我们清除关联,并在保存之前重新加载这些关联 当Hibernate在删除关联之后但在建立新关联之前刷新记录时,会出现异常,从而触发验证失败 也就是说,我们对关联有限制: 类实体{ ... 静态约束={ association1(minSize:1)//要求关联至少有1条记录 } } 更新持久记录的最佳方法是什么? 一些可能的选择: ===========================
类实体{
...
静态约束={
association1(minSize:1)//要求关联至少有1条记录
}
}
更新持久记录的最佳方法是什么?
一些可能的选择:
==============================================
[1] 创建新记录并复制属性:
def oldEntity=Entity.findByX(x)
如果(旧实体){
oldEntity.properties=newEntity.properties
保存(刷新:true)|
}
否则{
newEntity.save(刷新:true);
}
这里的问题是,这让人感觉很不舒服——创建一个被删除的实体,然后在一个活动实体上复制属性
==============================================
[2] 检索记录、更新、保存并禁用刷新:
sessionFactory.currentSession.flushMode=org.hibernate.flushMode.MANUAL
def existingEntity=Entity.findByX(x)
existingEntity.association1.clear()
existingEntity.association2.clear()
existingEntity.association1.add(新关联(…)
existingEntity.association2.add(新关联(…)
sessionFactory.currentSession.flushMode=org.hibernate.flushMode.AUTO
existingEntity.save(刷新:true)
不确定这种方法-不喜欢这样干扰Hibernate的状态管理
==============================================
[3] 永久性地将刷新模式设置为手动,并使用save()和save(flush:true)以级联方式保存记录:“全部删除孤立项”以确保关联得到管理
这里的问题是,这不是默认设置,而是依赖于我们来管理Hibernate的刷新
==============================================
总结:
所有这些方法似乎都有异味——有人能建议最不坏的方法吗——甚至是针对这种情况的最佳实践吗
谢谢
alex对我来说,如果你真的必须清除并重新创建这些关联,第二种方法是气味较少的方法
如果您需要操纵通过无效状态的模型,则将刷新模式设置为手动没有什么错。对我来说,如果您确实需要清除并重新创建这些关联,第二种方法是气味较少的方法
如果您需要操纵通过无效状态的模型,那么将刷新模式设置为手动并没有什么错。我们采用的解决方案是将提交模式设置为“提交”,它仅使用手动实体进行刷新。save(flush:true)调用以及在事务结束时(如果不回滚)调用 Config.groovy:
hibernate.flush.mode=“提交”
我们发现,在DataSource.groovy中设置此选项是一个怪癖,尽管这可能是更明显的地方。此外,新的线程要求我们手动设置-更改没有自动拾取
EntityService.groovy:
将org.codehaus.groovy.grails.commons.ConfigurationHolder作为CH导入
def会话工厂
。。。
sessionFactory.currentSession.flushMode=org.hibernate.flushMode.parse(CH.config.hibernate.flush.mode.toUpperCase())
后一种代码似乎仅在线程情况下才是必需的,因为新线程似乎不知道此设置,尽管它们具有上下文意识。我们采用的解决方案是将提交模式设置为“提交”,仅使用手动实体刷新。保存(flush:true)如果事务没有回滚,则在事务结束时调用和 Config.groovy:
hibernate.flush.mode=“提交”
我们发现,在DataSource.groovy中设置此选项是一个怪癖,尽管这可能是更明显的地方。此外,新的线程要求我们手动设置-更改没有自动拾取
EntityService.groovy:
将org.codehaus.groovy.grails.commons.ConfigurationHolder作为CH导入
def会话工厂
。。。
sessionFactory.currentSession.flushMode=org.hibernate.flushMode.parse(CH.config.hibernate.flush.mode.toUpperCase())
后一种代码似乎仅在线程情况下才是必需的,因为新线程似乎不知道此设置,尽管在其他情况下是上下文感知的。感谢您的回复,出现了第四个选项-在更新期间从hibernate删除(或逐出)记录,然后在执行更新后重新关联。感谢您的回复,出现第四个选项-在更新期间从hibernate中删除(或逐出)记录,然后在执行更新后重新关联。 class Entity { ... static constraints = { association1(minSize:1) //require association to have at least 1 record } } def oldEntity = Entity.findByX(x) if (oldEntity) { oldEntity.properties = newEntity.properties oldEntity.save(flush:true);| } else { newEntity.save(flush:true); } 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.flush.mode="commit" import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH def sessionFactory ... sessionFactory.currentSession.flushMode = org.hibernate.FlushMode.parse(CH.config.hibernate.flush.mode.toUpperCase())