【问题标题】:Hibernate 5 @ManyToMany cannot insert duplicate keyHibernate 5 @ManyToMany 无法插入重复键
【发布时间】:2019-03-14 11:29:54
【问题描述】:

我遇到了多对多关系的问题。我有一个带有 Set 的实体组织:

@Entity(name = "Organisation")
@Table(name = "organisation", uniqueConstraints = {@UniqueConstraint(name = "organisation_name_udx", columnNames = {"name"})})
@EntityListeners(EntityCreateListener.class)
public class Organisation implements Serializable, PatientListEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // Some fields are here

    @ManyToMany
    @Fetch(FetchMode.SELECT)
    @JoinTable(
        name = "billing_plan_organisation",
        joinColumns = {@JoinColumn(name = "organisation_id")},
        inverseJoinColumns = {@JoinColumn(name = "billing_plan_id")})
    private Set<BillingPlan> billingPlans = new HashSet<>();

    // Some fields are here

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Organisation that = (Organisation) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

这是 BillingPlan 实体:

@Entity
@Table(name = "billing_plan")
public class BillingPlan implements Serializable {

    @Id
    @Column(unique = true, name = "id", nullable = false)
    private String id = UUID.randomUUID().toString().toUpperCase();

    @NotNull
    @Column(unique = true, name = "plan_name", nullable = false)
    private String planName;

    // Some fields are here

    @Override
    public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         BillingPlan that = (BillingPlan) o;
         return id.equals(that.id) &&
                Objects.equals(planName, that.planName);
     }

     @Override
    public int hashCode() {
         return Objects.hash(id, planName);
    }
}

这是 BillingPlanOrganisation 实体:

@Entity
@Table(name = "billing_plan_organisation")
public class BillingPlanOrganisation implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "billing_plan_id", nullable = false)
    private String billingPlanId;

    @Id
    @Column(name = "organisation_id", nullable = false)
    private Long organisationId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BillingPlanOrganisation that = (BillingPlanOrganisation) o;
        return Objects.equals(billingPlanId, that.billingPlanId) &&
            Objects.equals(organisationId, that.organisationId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(billingPlanId, organisationId);
        }
}

当我创建一个新组织时,它会保存到数据库中。 当我向组织添加计费计划时 - 它仍然存在。 但是,当我向组织添加另一个计费计划时,我收到错误消息:

Violation of PRIMARY KEY constraint 'billingplanorg_id_pk'. Cannot insert duplicate key in object 'dbo.billing_plan_organisation'. The duplicate key value is (8551460d-ffc9-49a9-ae92-8aa1e6b851ec, 8175).

Hibernate 似乎正在尝试再次保存组织与第一个计费计划之间的现有连接。

P.S 以前,Hibernate 3 一切正常

【问题讨论】:

    标签: java sql-server hibernate many-to-many


    【解决方案1】:

    您是否以正确的方式覆盖了equals、hash 方法?

    例如

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Organisation )) return false;
        return id != null && id.equals(((Organisation ) o).id);
    }
    
    @Override
    public int hashCode() {
        return 31;
    }
    

    【讨论】:

    • 我尝试了级联 ALL、MERGE 和 PERSIST。没发生什么事。错误是一样的
    • 是的,我重写了 equals 和 hashCode 方法。我使用 lombok,但使用“经典”方法我有同样的错误。
    • 为什么需要 BillingPlanOrganisation 来连接表?您是否将其与 BillingPlan 和 Organization 一起保存?
    • 您是否不小心将其中一个 cmets 复制到您的答案中? edit 撤消该操作。它目前有资格被标记为“不是答案”和“应该是评论”。
    • @PeterŠály 这是别人写的老项目。出于某种原因,有 BillingPlanOrganisation 实体和它的存储库。一些服务正在使用这个实体
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 2012-06-03
    • 2017-07-03
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多