我正在使用 Spring Roo 开发一个 Spring Web 应用程序,仅用于生成持久层类(Web 应用程序本身正在使用 ZK 框架开发),使用 Roo 活动记录模式。
我有一个简单的问题是从数据库中检索实体(特别是从持久类User
中,相应的表被命名my_user
),让字段在 UI 中编辑,然后将修改后的实体保存在数据库中。
如果我做对了,在我的控制器类中,我有(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 键。该username
字段(不是键)--unique
在使用 Roo 生成时标记为。如果我尝试重新生成架构以消除对 的唯一要求username
,则合并的效果是在数据库上创建第二条记录(不给出任何例外),具有相同的用户名和不同的 Id 值(这显然不是我想要的行为应用)。
2)查看日志,hibernate(在JPA下使用的持久性提供程序)实际上尝试执行一条sqlINSERT
语句(我曾期望过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() 读取数据之间的实体分离有关,但这只是一个假设。
提前致谢,