可以将域类配置为在保存时插入新记录而不是更新吗?
Posted
技术标签:
【中文标题】可以将域类配置为在保存时插入新记录而不是更新吗?【英文标题】:Can domain classes be configured to insert a new record instead of updating when saved? 【发布时间】:2010-08-24 22:01:54 【问题描述】:当我更改域对象时,而不是更新数据库记录,我想存档旧记录并创建一个新记录。我想强制 GORM 自动执行此操作。
例如,如果我有这个域类:
class User
String username
String email
Boolean active
那我愿意
user.email = email
user.save()
将用户的活动标志设置为 false,保留旧电子邮件的记录。将插入具有新电子邮件地址和 active = true 的新记录。
这是一种常见的模式吗?在域类中是否容易做到,以便透明地发生?
【问题讨论】:
【参考方案1】:您可以在用户域类中使用 GORM 事件 beforeUpdate
(请参阅文档 here 和 here),如下所示应该可以工作(未经测试):
def beforeUpdate()
if (isDirty('email') //enters only if email was changed. Works only with Grails 1.3.x
User.withNewSession
//Create the new entry
new User(username:username, email:email).save()
//Update the old entry with the old email value
email = getPersistentValue('email')
【讨论】:
有趣,我没想到。但是如何获得新插入的用户(以替换旧实例)? 如果我在新会话中创建新用户,它将在另一个事务中,不是吗?理想情况下,如果出现故障,我希望它与事务的其余部分一起回滚。 @ataylor 是的,这是另一笔交易。只需检查 save() 的返回值并将错误传播到另一个事务以回滚@Pascal 我现在想到的唯一方法是:User.findByEmail(new_email),或将新用户 ID 存储在会话等范围内或闪光【参考方案2】:我能想到的一个选择是实现soft delete,然后保留一个新用户。我意识到这不是您所要求的,但我不知道如何通过一次保存来做到这一点。不理想的海事组织。
另一种(可能更好)的方法是使用Hibernate Envers 来“版本化”User
实体并保留更改历史记录。我不知道 Envers with Grails 的确切状态,但看起来有一个 plugin 。另见[grails-user] GORM & Envers / Audit History Tables。
【讨论】:
这也是一个很好的全局解决方案。你曾经用 Grails 尝试过 Envers 吗? @fabien7474:不,从来没有。老实说,我不知道 Envers with Grails 的当前状态是什么(实际上我并没有真正做 Grails)。以上是关于可以将域类配置为在保存时插入新记录而不是更新吗?的主要内容,如果未能解决你的问题,请参考以下文章