java - JPA 对所有者的多对多合并触发对连接表的删除

标签 java hibernate jpa orm many-to-many

我在 Customer 和 BusinessUnit 之间有多对多关系:

public class Customer extends AbstractEntity {

    @JoinTable(name = "CUS_BUS_UNITS", 
            joinColumns = {
                @JoinColumn(name = "CUS_ID", referencedColumnName = "CUS_ID")},
            inverseJoinColumns = {
                @JoinColumn(name = "BUS_ID", referencedColumnName = "BUS_ID")})
    @ManyToMany
    private Collection<BusinessUnit> businessUnits;
}

public class BusinessUnit extends AbstractEntity {

    @ManyToMany(mappedBy = "businessUnits")
    private Collection<Customer> customers;

}

当我调用 entityManager.merge(customer);在客户上(已经在数据库中,未更改)我在日志中看到这两个 sql 命令:

Hibernate: update CUSTOMERS set CUS_DESCR=?, CUS_NAME=?, CUS_ENABLED=? where CUS_ID=? Hibernate: delete from CUS_BUS_UNITS where CUS_ID=?

为什么 hibernate 试图从连接表中删除一条记录? 我只需要更新客户记录并可能更新连接表中的记录 - 取决于我是否添加或删除了客户的业务部门。不应更新、删除或插入业务单位。

编辑: 我的 equals/hashCode 是(在 AbstractEntity 中定义):

public int hashCode() {
    if (getId() != null) {
        return getId().hashCode();
    }
    return super.hashCode();
}
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    AbstractEntity other = (AbstractEntity) obj;
    if (getId() == null || other.getId() == null) {
        return false;
    }
    if (!getId().equals(other.getId())) {
        return false;
    }
    return true;
}

编辑 2 形式的转换器:

@FacesConverter("businessUnitConverter")
public class BusinessUnitConverter implements Converter {

    /**
     * {@inheritDoc}
     */
    @Override
    public String getAsString(FacesContext context, UIComponent component, Object object) {
        return ((BusinessUnit) object).getId().toString();
    }


    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        BusinessUnit businessUnit = new BusinessUnit();
        businessUnit.setId(Long.parseLong(value));
        return businessUnit;
    }

}

最佳答案

我找到了答案:http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

由于使用了 Collection(请参阅链接文章),此行为是正确的。我使用 Set 而不是 collection,它工作正常。

关于java - JPA 对所有者的多对多合并触发对连接表的删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14897067/

相关文章:

java - 以编程方式更改 ListView 行中对象的顺序

hibernate - 如何将构造函数映射与 Spring JPA 存储库结合使用

java - 批量插入多对多关系

xml - JAXB 和 JPA 将数据保存在数据库中

java - NullPointerException SQLiteAssetHelper

java - IntelliJ 模块与 Java 9 模块有什么关系吗?

java - 如何在java中通过https web服务发布xml

java - Hibernate 一对多映射 - 在 Java 中遵循这一点是正确的做法吗?

java - 使用实体列表的 JPA Criteria API 持久字段 IN 表达式

java - 使用 spring 配置 hibernate