【问题标题】:How to ignore field on domain object when using GORM save method使用 GORM 保存方法时如何忽略域对象上的字段
【发布时间】:2011-09-01 23:37:27
【问题描述】:

在我的应用程序中,我有一个用户域对象,其中包含一些字段,包括密码字段。密码字段是使用 JASYPT 加密的字符串。出于开发目的,我在启动时创建了一个硬编码的新用户。它看起来像这样:

User user = new User(
    userId:"user1", userFname:"Joe", 
    userLname:"Blow", userMinit:"A",
    userEmail:"joe@blow.com", userPword:"password").save()

当调用 save() 时,我相信在后台调用休眠 saveOrUpdate()。它将新的域对象字段值与现有的域对象字段值进行比较,以决定是否应该将记录插入到数据库中,或者是否应该只更新已经存在的记录。

由于 JASYPT 加密,密码字段始终是一个新值,因此每次都会插入一条新记录。

INSERT INTO USER VALUES(1,'joe@blow.com',
    'Joe','user1','Blow','A','','','',
    'gIkUvM9b6d5vrEhkKzqKz0U7uxqRpZFhiQrrBTDbKX0=')
INSERT INTO USER VALUES(2,'joe@blow.com',
    'Joe','user1','Blow','A','','','',
    'yap0S0mCb2CpGngcANpSWoLqlL6SozLYK4WbKYHSVEw=')

这是域类:

@Table(name="user")
class User {

    String userId
    String userFname
    String userLname
    String userMinit
    String userEmail
    String userPword
    String userMisc1 = ""
    String userMisc2 = ""
    String userMisc3 = ""

    public User(){};

    static mapping = {
        version false
        columns {
            userId      column:'user_id'
            userFname   column:'user_fname'
            userLname   column:'user_lname'
            userMinit   column:'user_minit'
            userEmail   column:'user_email'
            userPword   column:'user_pword'
            userMisc1   column:'user_misc1'
            userMisc2   column:'user_misc2'
            userMisc3   column:'user_misc3'
        }

        userPword type: GormEncryptedStringType
     }

    static constraints = {}
}

有没有办法告诉 GORM 在保存域对象时忽略密码字段,这样我就不会在数据库中一遍又一遍地使用同一个用户?

感谢您的帮助。

【问题讨论】:

    标签: hibernate grails grails-orm hsqldb


    【解决方案1】:

    响应 OPs 评论,您可以通过向域类添加瞬态属性来使属性在 grails 中不持久:

    static transients = [ "userPword", "anotherOne" ]
    

    但如上所述,这对您的问题没有帮助。

    谢谢,吉姆。

    【讨论】:

      【解决方案2】:

      告诉 GORM 忽略您的密码字段不会解决您的问题。如果你创建一个新实例然后保存它,hibernate 将总是尝试插入这个对象,因为它到目前为止对它一无所知——它甚至没有一个 id。

      它进行更新的唯一方法是首先从数据库中获取现有记录,更新属性,然后保存。

      几乎每个人都选择 jjczopek 建议的解决方案 - 检查它是否存在,如果不存在,则创建并保存。

      顺便说一句,我可能会在 userId、userEmail 上为用户记录设置唯一约束 - 顺便说一下,如果你这样做,另一种处理问题的方法是静默捕获添加相同约束时将引发的唯一约束错误用户 ID 和用户电子邮件。

      【讨论】:

      • 我还建议将 user_id 设置为 id 列映射
      【解决方案3】:

      您可以覆盖 equals 和 hashCode,这是 Hibernate 用来确定对象是否脏的。

      但是,在您的具体示例中,我认为 jjczopek 的答案更好,因为您正在处理一种特殊情况,而不是您希望整个应用程序的行为。消除整个应用程序中密码更改的更新将对通过任何类型的 UI 进行的用户管理产生相当严重的影响。

      【讨论】:

        【解决方案4】:

        在保存新用户之前,您可以检查该用户是否已经存在:

        User user = User.findByUserId("user1") ?: new User(userId:"user1", userFname:"Joe",
                                                        userLname:"Blow", userMinit:"A", 
                                                        userEmail:"joe@blow.com",
                                                        userPword:"password").save(flush: true)
        

        【讨论】:

        • 这是一种处理方式,我可以使用它。但我真的很想知道我所问的是否可能。谢谢。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-26
        • 1970-01-01
        • 2011-07-24
        • 2013-08-10
        • 1970-01-01
        相关资源
        最近更新 更多