【发布时间】:2015-08-18 06:44:48
【问题描述】:
我正在使用 hibernate 的 EntityManager 来保存一个对象,然后对其进行更新。我的代码看起来像:
@PersistenceContext(unitName = "demoPU")
private EntityManager em;
E e = new E();
e.setDescription("Description");
e = em.merge(e);
em.flush();
e.setDescription("newDescription");
e = em.merge(e);
em.flush();
类 E 的 ID 是使用 @PrePersist 生成的。
休眠日志看起来像:
Hibernate: insert into E (Description, ID) values (?, ?, ?)
Hibernate: insert into E (Description, ID) values (?, ?, ?)
所以基本上hibernate试图用相同的ID插入相同的对象两次。这反过来又给出了以下异常:
org.hsqldb.HsqlException: integrity constraint violation: unique constraint or index violation; SYS_PK_10253 table: POLICY
有人可以告诉我为什么休眠运行insert 语句而不是update,即使我使用实体管理器merge 来保存和更新对象?在这种情况下,我如何才能真正更新对象?
编辑:E 类看起来像:
@Entity
@Table(name = "E")
public class E {
@Id
@Column(name="ID",nullable = false)
private String id;
@Basic(optional = false)
@Column(name = "Description", nullable = false)
private String Description;
// Getters setters etc
public String getId(){
if(this.id == null ){
this.setId(UUID.randomUUID().toString());
}
return id;
}
@PrePersist
private void verifyPrimaryKeyAssigned(){
getId();
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
Policy other = (Policy) obj;
if (getId() == null) {
if (other.getId() != null)
return false;
} else if (!getId().equals(other.getId()))
return false;
return true;
}
}
【问题讨论】:
-
你能不能给 ddl 看一下密钥
SYS_PK_10253 -
merge 会导致 onFlushDirty,(而且你已经弄乱了你的实体,所以它很脏)它试图再次插入它是正确的
-
你的第一次合并不应该是持久化吗?
-
@Jens :它没有被记录,但我相信这是 E 的 Id 列(用@Id 注释)的唯一约束。
-
这通常发生在您更改对象的签名时。当您恢复对象时,不要尝试重新启动它,只需按原样传递即可。