问题描述
|
在我的应用程序中,我有一个用户域对象,其中包含一些字段,包括密码字段。密码字段是使用JASYPT加密的字符串。出于开发目的,我在启动时创建了一个经过硬编码的新用户。看起来像这样:
User user = new User(
userId:\"user1\",userFname:\"Joe\",userLname:\"Blow\",userMinit:\"A\",userEmail:\"[email protected]\",userPword:\"password\").save()
当我调用save()时,我相信在后台会调用休眠的saveOrUpdate()。它正在将新的域对象字段值与已经存在的域对象字段值进行比较,以决定是否应将记录插入数据库中,还是应该只更新已存在的记录。
由于JASYPT加密,由于password字段始终是一个新值,因此每次都会插入一个新记录。
INSERT INTO USER VALUES(1,\'[email protected]\',\'Joe\',\'user1\',\'Blow\',\'A\',\'\',\'gIkUvM9b6d5vrEhkKzqKz0U7uxqRpZFhiqrrBTDbKX0=\')
INSERT INTO USER VALUES(2,\'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在保存域对象时忽略密码字段,这样我就不会一次又一次地在数据库中遇到相同的用户?
谢谢你的帮助。
解决方法
保存新用户之前,可以检查该用户是否已经存在:
User user = User.findByUserId(\"user1\") ?: new User(userId:\"user1\",userFname:\"Joe\",userLname:\"Blow\",userMinit:\"A\",userEmail:\"[email protected]\",userPword:\"password\").save(flush: true)
,响应OP注释,您可以通过向域类中添加一个transients属性来使属性在grails中不持久:
static transients = [ \"userPword\",\"anotherOne\" ]
但是如上所述,这对您的问题没有帮助。
谢谢,吉姆。
,您可以重写equals和hashCode,这是Hibernate用于确定对象是否脏的内容。
但是,在您的特定示例中,我认为jjczopek的答案更好,因为您正在处理一种特殊情况,而不是整个应用程序所需的行为。消除整个应用程序中密码更改的更新将通过任何类型的UI对用户管理产生非常严重的影响。
,告诉GORM忽略您的密码字段不会解决您的问题。如果创建一个新实例然后保存它,则hibernate将始终尝试插入该对象,因为到目前为止,它对它一无所知-它甚至没有ID。
进行更新的唯一方法是,如果您首先从数据库中获取现有记录,先更新属性,然后保存。
jjczopek建议的解决方案几乎每个人都去-检查它是否存在,如果不创建并保存。
顺便说一句,我可能会在用户记录的userId,userEmail上设置唯一约束-顺便说一句,如果您这样做,处理问题的另一种方法是静默捕获在添加相同的userId和userEmail时将抛出的唯一约束错误。 。