【问题标题】:Saving entitities back to db with Spring Roo active record pattern使用 Spring Roo activerecord 模式将实体保存回数据库
【发布时间】:2015-03-11 10:38:54
【问题描述】:

我正在使用 Spring Roo 开发一个 Spring Web 应用程序,仅用于生成持久层类(Web 应用程序本身是使用 ZK 框架开发的),使用 Roo 活动记录模式。

我有一个简单的问题是从数据库中检索一个实体(特别是从一个持久类User,相应的表被命名为my_user),让字段在UI中编辑,然后保存修改db 上的实体。

如果我做对了,在我的控制器类中,我有用于 (A) 检索具有 username 可用的用户数据的方法:这是通过调用来完成的

User user = User.findUsersByUsernameEquals(username).getSingleResult()

并且似乎工作正常(数据正确显示在 UI 上)和 (B) 将实体数据保存回数据库。为此我称之为方法

user.merge()

问题是调用merge()时会产生如下异常,导致修改后的数据没有保存到数据库中。

org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException:        
org.hibernate.exception.ConstraintViolationException: could not execute statement[SQL: 1062, 23000]
...
caused by:
...
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
Duplicate entry '<username value>' for key '...'

注意事项:

1) User 实体作为自动生成的 Id 键。使用 Roo 生成时,username 字段(非键)标记为 --unique。如果我尝试重新生成架构以消除对username 的唯一要求,则合并的效果是在数据库上创建第二条记录(不给出任何例外),具有相同的用户名和不同的 Id 值(这显然不是所需的我的应用程序的行为)。

2)查看日志,hibernate(在 JPA 下使用的持久性提供程序)实际上尝试执行 sql INSERT 语句(我原以为是 UPDATE):

[DEBUG] (org.hibernate.SQL:104) insert into my_user (address, email, enabled, firstname, password, surname, telephone, username, version) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into my_user (address, email, enabled, firstname, password, surname, telephone, username, version) values (?, ?, ?, ?, ?, ?, ?, ?, ?)

3) 如果我调用 user.persist() 而不是 user.merge() 我得到与以前相同的异常(这只是一次尝试,如果我理解,调用 .persist() 不应该是保存修改实体的正确方法对)。

我刚刚开始 JPA 和 Roo 编程,所以我不确定我是否以正确的方式做事。我的印象是这个问题可能与我使用 findUsersByUsernameEquals 和 merge() 读取数据之间的实体分离有关,但这只是一个假设。

提前致谢,

【问题讨论】:

    标签: java spring hibernate jpa roo


    【解决方案1】:

    我想我已经找到了解决方案,感谢这个帖子:JPA Hibernate merge performs insert instead of update

    问题是由于 Roo 在创建 jpa 实体时自动添加了 version 字段。我用一组INSERT INTO 填充我的初始数据库,我没有为此字段设置值,导致它被初始化为null。

    如果我在 INSERT INTO 语句中将其设置为 0,则代码可以正常工作。 (在使用 persist() 从 java 代码直接创建实例时,可能永远不会发生这种情况,我猜这会正确初始化版本字段)

    【讨论】:

    • 感谢有关“version”字段的提示,它有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多