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

在Grails中对域实例进行版本控制以供审批,grails,gorm,Grails,Gorm,我正在寻找扩展Grails CRUD生成功能的最佳方法。它应该是一个Grails插件,为以下功能提供额外的生成器: 扩展域实例上的任何更改都应保存(作为版本) (它的)历史 一个实例只能有一个版本处于活动状态 用户应该能够激活实例的一个版本( 当前活动实例(应停用)未创建 由他(4眼原则) 有不同的视野是很好的 对Grails开箱即用脚本的干预应该尽可能小。 到目前为止,我确定了3种实施设计策略: 具有相同架构的镜像表,其中包含版本(双版本) 域/表的计数)。将复制激活的版本 到本机域,反之

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

  • 扩展域实例上的任何更改都应保存(作为版本) (它的)历史
  • 一个实例只能有一个版本处于活动状态
  • 用户应该能够激活实例的一个版本( 当前活动实例(应停用)未创建 由他(4眼原则)
  • 有不同的视野是很好的
对Grails开箱即用脚本的干预应该尽可能小。 到目前为止,我确定了3种实施设计策略:

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

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

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

    我已经创建了两个字段:InternalVersione disabled。每个需要可版本化的类都必须实现一个称为可版本化的接口

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

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

    每个报价可以有一个或多个版本,其中只有最后一个版本有效。每个报价及其版本都是在与特定客户协商的基础上生成的。通过这种方式,客户要求我们报价,如果出于某种原因他不喜欢价格(例如),我们可以生成具有一定折扣的新版本。每个报价都有一个唯一的代码,后面是当前版本,例如:QT-000022/0(第一个版本)、QT-000022/1(第二个版本)

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

    clone方法标识该类实现可版本化接口,并执行以下操作:

    oldQuote.disabled = true
    newQuote.internalVersion = oldQuote.internalVersion + 1
    
    这样可以确保只启用一个版本


    我希望你能理解我的方法。

    从未尝试过,但你可能会觉得有趣?@tim_yates请将其作为答案发布,这样我就可以接受了。在您的建议中,使用了一个名为Envers的hibernate插件。它实现了我的问题中描述的第一个策略。它很好用。唯一的缺点是,数据库更改必须在事务内部,而控制器则不是这样。独立于策略,利用Grails中的动态支架来实现它们是一个好主意。对于每个需要特殊功能的域,创建一个scaffold=true的空控制器。然后安装模板并修改它们。例如,更改列表操作以过滤掉非活动对象。覆盖克隆方法是个好主意。如果在列上创建索引,则不会有任何性能问题。您仍然有2.nd选项的缺点,即它对应用程序不透明。每个查询至少应该知道“已禁用”列。