除了这样做的明显的性能含义之外,不是在Config.groovy中设置grails.gorm.autoFlush = true和grails.gorm.failOnError = true的好的技术原因是什么?
发布于 2011-01-15 23:09:00
GORM是Hibernate的包装器(至少这是实现之一--现在也有各种NoSQL实现,比如Redis)。通过将autoFlush设置为true,您将拒绝Hibernate优化它对数据库的调用。例如,您可能会让它插入,然后更新,当一个插入可能已经足够。从本质上讲,这并没有什么坏处,只是没有必要,效率也不高。Hibernate非常聪明,可以知道何时需要写入数据库,并且可以进行优化--您已经抽象出了这个问题。
设置failOnError将导致当您试图保存不验证的域对象时,保存将引发异常。在构建涉及从用户输入创建对象的应用程序时,对象不进行验证是非常正常的--缺少输入、格式错误等。异常处理应该保存在异常和错误中--它不应该用于应用程序的正常流。当对象被成功保存或空时,save()返回对象,这为您提供了一种更方便的方法,可以将验证作为应用程序流的一部分来处理,而不是将试捕获块放在各处。
Peter (“Grails”的作者)写了一系列伟大的“Gotchas”文章,他在文章中更详细地讨论了其中的一些问题--非常值得一读:part 1,part 2 & part 3。
发布于 2013-02-13 18:10:30
我曾经使用过,并且相信我有很好的理由想和你分享。
为什么使用grails.gorm.autoFlush = true__?
因为当我调用save()时,没有真正地保存实体/域就是没有执行我告诉API要做的事情。当Hibernate在执行前16行刷新时,它会引起许多头痛,并且会给调试带来痛苦。您的团队不是Java开发人员,这很痛苦。
Grails借鉴了Ruby的活动记录模式( Ruby直接调用持久性方法,比如domain.save),但是当调用save()时,Grails确实会执行持久记录模式,但是Grails并不这样做,因为它们向API用户/开发人员隐藏了“Hibernate会话”。使用这个配置参数可以解决GORM的一个严重的泄漏抽象失败。
一旦设置好了,如果您真的需要Hibernate的单元工作模式(它会链接SQL调用并只执行一次),那么就在需要时使用domain.save(flush:false)即可。
为什么使用grails.gorm.failOnError = true
永远不要对用户隐藏异常。所有优秀的Java程序员都知道这一点。如果您“真的”需要隐藏,请将其记录为警告。但不幸的是,当Grails验证失败时(没有日志!)让程序员变得盲目,对于那些不知道的新手来说,这真的很难。最有经验的人只会说“很容易调整”,但这只是一种比更好的方式更恶毒的方式。
为了
起见,这些GORM漏出的抽象是我过去对Grails唯一的抱怨。现在,他们刚刚使用了这个配置参数.
。
发布于 2013-10-31 02:42:29
Peter Ledbrook关于GORM的一系列文章:
虽然我不同意他关于Hibernate会话刷新所做的事情。他说,“刷新:真正迫使Hibernate立即对数据库进行所有更改”。这只会发生在非事务性上下文中,因为当您在事务中时,从Hibernate会话中刷新的#SQL语句将在事务性RDBMS的回滚段中执行。因此,在事务提交之前,它们不会被断断续续地保存。
当在事务中执行其他与数据库无关的操作时,比如发送确认电子邮件,您想知道在验证中没有显式声明的约束或DB运行时错误是否发生过,例如,您发送了确认邮件。
我的建议是,autoFlush (grails.gorm.autoFlush = true)策略本身并没有错。您必须在一开始就决定是否要使用它,这样开发人员就可以相应地编写代码,因为他们知道是否需要显式执行刷新,或者Hibernate将在您的事务方法结束时为他们编写代码。
另一个需要考虑的常见用例是,您是否希望使用GORM执行批处理操作。如果不刷新Hibernate会话的所有SQL操作数量,就会遇到问题。
https://stackoverflow.com/questions/4702515
复制相似问题