Ошибка дублирования записей @ManyToMany когда поле первичного ключа не указано

У меня есть две сущности, связанные отношением many-to-many. Вот их реализация:

@Setter
@Getter
@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @EqualsAndHashCode.Include
    private Long id;
    @NaturalId
    @Column(name = "admin_server_id")
    private long adminServerId;

    //Бренды, к которым пользователь имеет доступ
    @ManyToMany(
            fetch = FetchType.LAZY,
            cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
            name = "users_brands",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "brand_id",
                    foreignKey = @ForeignKey(name = "user_brand_FK")
            )
    )
    private Set<Brand> brands = new HashSet<>();

А вот реализация брендов:

@Entity
@Table(name = "brands")
@Setter
@Getter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@AllArgsConstructor
@NoArgsConstructor
public class Brand {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @EqualsAndHashCode.Include
    private Long id;

    @EqualsAndHashCode.Include
    @Column(name = "server_id", unique = true)
    private Long serverId;

    @Column(name = "name")
    private String name;

    @Column(name = "logo")
    private String logo;

    //Пользователь, которому доступен бренд
    @ManyToMany(
            mappedBy = "brands",
            fetch = FetchType.LAZY)
    private Set<User> users = new HashSet<>();

Через рест апи с сервера приходят пользователи, которые регистрируются в данном микросервисе. У пользователей бренды могут быть такие, которые уже сохранены в базе. Это нормальная ситуация. Поле id у брендов записывается в serverId и затем обнуляется, это сделано для того, чтобы избежать ошибок, связанных с тем, что такой id уже есть в базе. Проблема в том, что в ситуации, когда в микросервисе регистрируется пользователь, бренды которого уже есть в базе, бренды сохраняются в происходит ошибка из-за нарушения уникальности поля serverId, а это поле должно быть уникальным намеренно. Из-за этой ошибки не сохраняются ни бренды, ни пользователь. Я пробовал использовать метод EntityManager.merge для сохранения пользователя с массивом брендов, но происходит та же самая ошибка Duplicate entry '30' for key. Я предполагаю, что это из-за того, что в брендах не указаны значения id и энтити менеджер не может при мерже найти существующую в базе запись и выполнить ее обновление. Вместо обновления происходит создание новой записи и возникает дублирование уникального поля.

Как исправить эту ошибку? Что делать, чтобы при таком подходе к реализации сервиса происходило обновление существующих брендов?


Ответы (0 шт):