在 Grails 中对域实例进行版本控制以供批准

Posted

技术标签:

【中文标题】在 Grails 中对域实例进行版本控制以供批准【英文标题】:Versioning domain instances for approval in Grails 【发布时间】:2014-02-01 06:23:00 【问题描述】:

我正在寻找扩展 Grails CRUD 生成功能的最佳方法。它应该是一个 Grails 插件,为以下功能提供额外的生成器:

应保存扩展域实例的任何更改(作为版本 它)的历史 一个实例只能激活一个版本 用户应该能够激活实例的一个版本( 当前活动的实例应该被停用),它没有被创建 由他(四眼原则) 有差异视图很不错

对 Grails 开箱即用脚本的干预应尽可能少。 到目前为止,我确定了 3 种实施设计策略:

    具有相同架构的镜像表,其中包含版本(双精度 域/表的计数)。激活的版本将被复制 到本机域,反之亦然。 在域类中使用鉴别器。一些新的列将被添加到域中(如状态 [active,notActive]、lastUpdatedBy、 最后更新日期…) (反)使用 BLOB 将实例序列化到特殊域(例如,作为 JSON 的 domain.properties)

任何解决方案都有利有弊。实施它的最佳方法是什么?或许还有更简单的方法。

【问题讨论】:

从未尝试过,但您可能会觉得refaktor.blogspot.co.uk/2012/08/… 有趣? @tim_yates 请将其发布为答案,以便我接受。在你的建议中使用了一个名为 Envers 的休眠插件。它实现了我的问题中描述的第一个策略。它工作正常。唯一的缺点是,数据库更改必须在事务中,而控制器则不是这样。 独立于策略,利用 Grails 中的动态脚手架来实现它们是个好主意。对于每个需要特殊功能的域,创建一个空的控制器,脚手架 = true。然后安装模板并修改它们。例如。更改列表操作以过滤掉非活动对象。 【参考方案1】:

我一直在 Grails 中开发一个系统,该系统充分利用了版本概念(正如您在上面提到的)。我的方法是您问题中列出的第二个方法。

我创建了两个字段:internalVersion e disabled。每个需要是 Versionable 的类都必须实现一个名为 Versionable 的接口。

我将尝试在此处解释使用版本功能所必需的场景之一(请原谅我的英语)。

使用这个概念的系统是一个商业系统,其中有一个名为 Quote 的类。

每个报价都可以有一个或多个版本,其中只有最后一个版本有效。每个报价及其版本都是根据与特定客户的协商生成的。这样,客户向我们询问报价,如果由于某种原因他不喜欢价格(例如),我们可以生成带有一些折扣的新版本。每个报价都有一个唯一的代码,跟在当前版本之后,例如:QT-000022/0(第一版)、QT-000022/1(第二版)。

为了生成一个新版本,我使用了一种克隆当前对象的方法(使用一种完整且深度的另存为)。我将所有内容(属性和集合)复制到一个新对象中。

clone 方法标识该类实现了 Versionable 接口并执行以下操作:

oldQuote.disabled = true
newQuote.internalVersion = oldQuote.internalVersion + 1

这样可以确保只启用一个版本。

希望你能理解我的做法。

【讨论】:

覆盖克隆方法是个好主意。如果在列上创建索引,它不会有任何性能问题。您仍然有 2.nd 选项的缺点,即它对应用程序不透明。每个查询都应该知道至少“禁用”列。

以上是关于在 Grails 中对域实例进行版本控制以供批准的主要内容,如果未能解决你的问题,请参考以下文章

在 Grails 控制器中对父子元素进行排序

如何在 Grails 2.0 服务中对 i18n 注入 messageSource 的使用进行单元或集成测试

Java中对域和静态方法的访问不具有多态性

在 Grails 中对服务进行单元测试时如何模拟请求

是否可以在已批准测试的构建时上传新构建以进行测试审核?

Grails 中的 Spring Security 提供授权