使用GORM保存方法时如何忽略域对象上的字段

时间:2011-05-25 17:45:24

标签: hibernate grails gorm hsqldb

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

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

当调用save()时,我相信在后台调用了hibernate 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=')

这是Domain类:

@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在保存域对象时忽略密码字段,这样我就不会在数据库中一遍又一遍地使用同一个用户?

感谢您的帮助。

4 个答案:

答案 0 :(得分:6)

响应OP注释,您可以通过向域类添加瞬态属性来使属性在grails中非持久性:

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

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

谢谢,吉姆。

答案 1 :(得分: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)

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

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

顺便说一句,我可能会对userId设置唯一约束,userEmail设置用户记录 - 顺便说一句,如果你这样做,另一种处理问题的方法是静默捕获添加相同的约束错误。 userId& USEREMAIL。