【问题标题】:Hibernate failing to update objectHibernate 无法更新对象
【发布时间】: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 注释)的唯一约束。
  • 这通常发生在您更改对象的签名时。当您恢复对象时,不要尝试重新启动它,只需按原样传递即可。

标签: java hibernate jpa


【解决方案1】:

如果您想第一次持久化实体,我认为使用“持久”而不是“合并”会更清楚。

在您的示例中,无需调用“合并”两次,因为您从第一次合并中获得了托管实体,并且您正在更改从合并中获得的实体,您的更改将在事务提交时自动保留。

【讨论】:

    猜你喜欢
    • 2012-09-11
    • 2013-11-23
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多