休眠-删除有关ElementCollection

时间:2018-10-31 11:02:40

标签: java hibernate

@Embeddable
class Y {
    protected Y(){}
    @Column(nullable = false)
    int i;
    @Column(nullable = false)
    int j;
}
@Entity
class X {
    protected X(){}
    @Id
    @Column(name = "id")
    int id;

    @ElementCollection(fetch = FetchType.EAGER)
    Set<Y> s = new HashSet<>();
}

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
X a = new X();
a.s.add(new Y());

session.save(a);
transaction.commit();
session.close();

休眠映射表x_s包含3列,分别是x,i和j的ID。 但是,如果通过更新这样使分离的对象再次持久化:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
X x = session.get(X.class, 0);
transaction.commit();
session.close();

Session session1 = sessionFactory.openSession();
Transaction transaction1 = session1.beginTransaction();
session1.saveOrUpdate(x); // and select or update should execute
transaction1.commit();
session1.close();

奇怪的是,除了select之外,hibernate会删除并插入,上面的代码会生成:

Hibernate: select x0_.id as id1_0_0_, s1_.X_id as X_id1_1_1_, s1_.s_i as s_i2_1_1_, s1_.s_j as s_j3_1_1_ from X x0_ left outer join X_s s1_ on x0_.id=s1_.X_id where x0_.id=?
Hibernate: delete from X_s where X_id=? and s_i=? and s_j=?
Hibernate: insert into X_s (X_id, s_i, s_j) values (?, ?, ?)
Hibernate: select x_.id from X x_ where x_.id=?
Hibernate: delete from X_s where X_id=? and s_i=? and s_j=?
Hibernate: insert into X_s (X_id, s_i, s_j) values (?, ?, ?)

根据此answer,它说原因是表x_s没有pk。但是,休眠生成的表x_s已经将所有3列用作组合的pk。

消除这些插入和删除命令的唯一方法似乎是将Set<Y>更改为List<Y>,hibernate会自动添加列顺序并将命令和x_id组合为pk。但是从数据库架构视图来看,没有实质性差异

P.S 我使用休眠5.3

1 个答案:

答案 0 :(得分:0)

很明显,JPA看到对象不相等是清除并重新插入的。 请尝试覆盖equals()对象的hashcode()Embeddable。使用默认实现时,仅通过引用就可以认为对象是相等的,在您的情况下不会如此。