Hibernate 5 @ManyToMany не может вставить дубликат ключа - PullRequest
0 голосов
/ 14 марта 2019

У меня проблема с отношением «многие ко многим». У меня есть организация Entity с 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

1 Ответ

0 голосов
/ 14 марта 2019

Правильно ли вы переопределили метод равенства, методы хеширования?

, например

@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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...