在我的Grails应用程序中,我已经将域类的对象引导为:
def user1 = new Users(userID: 1, name: "John Doe")
user1.save()
在我的仪表板控制器中,我检索了对象并将其属性名称修改为:
Users userObj = Users.get((Long) 1)
println(userObj as JSON); // This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
userObj.name = "anonymous"
现在我创建一个新的Users对象来检索具有与
相同的ID 1的已更改对象Users otherUserObj = Users.get((Long) 1) // **Line 2** Is this retrieving from database or from GORM session?
print(otherUserObj as JSON)// This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"anonymous"}
但是数据库中对象的值不会改变。即使我在另一个控制器中检索相同id 1的Users对象,它也会给我初始对象而不是修改为:
Users userObjAtDifferentController = Users.get(1);
print(userObjAtDifferentController) //This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
我的问题是,如果数据库中的值没有改变,为什么它给了我第2行的修改对象,尽管我已经使用GORM查询检索了对象(我猜应该从数据库)?
我还尝试在修改后使用save()但结果是一样的。
userObj.save() //doesn't show the changes in database.
答案 0 :(得分:2)
我的猜测是对象没有保存到数据库,因为某些约束无效。您可以通过将save()
的来电替换为save(failOnError: true)
来确定是否属于这种情况。如果我的猜测是正确的,如果保存到数据库失败,将抛出异常。
答案 1 :(得分:1)
在域对象上调用save()方法时,它可能不会立即在数据库中保留。为了将更改的值保留到数据库,您需要执行以下操作。
userObj.save(flush: true)
通过使用flush,您告诉GORM立即在数据库中保留。
在某些情况下,当验证失败时,数据仍然不会在数据库中持久存在。 save()方法将以静默方式失败。要捕获验证错误并立即保存到数据库,您需要执行以下操作
userObj.save(flush:true, failOnError:true)
如果存在验证错误,则GROM将抛出ValidationException(http://docs.grails.org/latest/api/grails/validation/ValidationException.html)
答案 2 :(得分:1)
你需要考虑两件事:
如果你执行save()
,它只保留在休眠会话中,直到你刷新它,更改不会在数据库中持续存在。因此,最好执行save(flush:true, failOnError: true)
并输入try/catch
阻止并打印例外。
另一个重要的事情是,controller
中的方法需要使用@Transactional
注释,如果没有它,您的更改不会在数据库中保留,您将遇到Connection is read-only. Queries leading to data modification are not allowed.
异常
希望这会有所帮助,如果您的问题得到解决,请与我们联系。快乐的编码。 :)