简体   繁体   English

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

[英]How to ignore field on domain object when using GORM save method

In my application I have a User domain object that has a handful of fields in it including a password field.在我的应用程序中,我有一个用户域 object,其中包含一些字段,包括密码字段。 The password field is an encrypted String using JASYPT.密码字段是使用 JASYPT 加密的字符串。 For development purposes I am creating a new user on startup that is hard coded.出于开发目的,我在启动时创建了一个硬编码的新用户。 It looks like this:它看起来像这样:

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

When the save() is called I believe that in the background the hibernate saveOrUpdate() is being called.当调用 save() 时,我相信在后台调用了 hibernate saveOrUpdate()。 It is comparing the new domain objects field values against already existing domain object field values to decide if the record should be inserted into the db or if it should just update an already existing record.它将新域对象字段值与现有域 object 字段值进行比较,以确定是否应将记录插入到数据库中,或者是否应仅更新现有记录。

Since the password field is always going to be a new value because of the JASYPT encryption it is inserting a new record every time.由于 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=')

Here is the Domain class:这是域 class:

@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 = {}
}

Is there a way to tell GORM to ignore the password field when saving the domain object so I don't end up with the same user over and over in the DB?有没有办法告诉 GORM 在保存域 object 时忽略密码字段,这样我就不会在数据库中一遍又一遍地使用同一个用户?

Thanks for any help.谢谢你的帮助。

Responding to the OPs comment, you can make properties non persistent in grails by adding a transients property to the domain class:响应 OPs 评论,您可以通过向域 class 添加瞬态属性来使属性在 grails 中非持久化:

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

But as pointed out above, this wouldn't help with your problem.但如上所述,这对您的问题没有帮助。

Thanks, Jim.谢谢,吉姆。

Before saving new user, you can check if that user already exists:在保存新用户之前,您可以检查该用户是否已经存在:

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

You could override equals and hashCode, which is what Hibernate uses to determine if the object is dirty.您可以覆盖 equals 和 hashCode,这是 Hibernate 用来确定 object 是否脏的。

However, in your specific example, I think jjczopek's answer is better, as you're dealing with one special case, as opposed to behavior you desire for the entire application.但是,在您的具体示例中,我认为 jjczopek 的答案更好,因为您正在处理一种特殊情况,而不是您希望整个应用程序的行为。 Eliminating updates for password changes in the entire application would have a pretty severe impact on user management through any sort of UI.消除整个应用程序中密码更改的更新将对通过任何类型的 UI 进行的用户管理产生相当严重的影响。

Telling GORM to ignore your password field will not solve your problem.告诉 GORM 忽略您的密码字段不会解决您的问题。 If you create a new instance and then save it, hibernate will always try and insert this object since it knows nothing about it up to this point - it doesn't even have an id.如果您创建一个新实例然后保存它,hibernate 将始终尝试插入此 object,因为它对此一无所知 - 它甚至没有 id。

The only way it will do an update is if you fetch the existing record from the DB first, update attributes, then save.它进行更新的唯一方法是首先从数据库中获取现有记录,更新属性,然后保存。

Pretty much everybody goes for the solution jjczopek has suggested - check if it exists, if not create and save.几乎每个人都选择 jjczopek 建议的解决方案 - 检查它是否存在,如果不存在,则创建并保存。

BTW, I would probably have unique constraints set on userId, userEmail for a User record - incidentally, if you do this, another way to handle your problem is to silently catch the unique constraint error that will be thrown when adding the same userId & userEmail.顺便说一句,我可能会在 userId、userEmail 上为用户记录设置唯一约束 - 顺便说一下,如果你这样做,另一种处理问题的方法是静默捕获添加相同 userId 和 userEmail 时将引发的唯一约束错误.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM