Проблема с обновлением коллекций после перехода на Spring boot 3.0 и Java 17.

у меня действительно странная проблема с сохранением существующего пользователя в базе данных**, и эта ошибка не реплицируется для каждой записи**, и это то, чего я обычно не понимаю. У меня есть пользовательская сущность с таблицей карт user_roles с двумя полями user_id и role_id, которые находятся в собственном ключе этой таблицы (users_roles).

**До перехода на Java 17 и Spring Boot 3.0 (с Java 11 и Spring Boot 2.7) эта проблема не возникала **но после сохранения пользователя, который сопоставляет новый набор ролей (который равен старому набору ролей, метод равен( ) возвращает true в этом случае) у меня проблема с тем, что Spring пытается вставить дублированную запись в таблицу user_roles, и это вызывает ошибку «JdbcSQLIntegrityConstraintViolationException, нарушение уникального индекса или первичного ключа»

      @Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User implements UserDetails {

    @Id
    private int id;


    @Column(nullable = false, unique = true, length = 100)
    private String login;

    
    @Column(nullable = false, length = 100)
    @ToString.Exclude
    private String password;

    @Column(nullable = false, name = "is_active")
    private boolean active;

    private LocalDateTime validFrom;

    private LocalDateTime validTo;

    @ManyToMany(fetch = FetchType.EAGER,cascade = {CascadeType.PERSIST,CascadeType.MERGE})
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles;

    @UpdateTimestamp
    private LocalDateTime lastModifiedAt;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserState state;
}

я пытался переопределить метод равенства и хэш-код, это не помогло (даже пытался дать просто вернуть true, как для роли, так и для пользователя), пытался изменить типы каскада и не знаю случая ошибки

** если новая сущность, которая будет сохранена, будет иметь набор ролей СТАРЫЙ ПОЛЬЗОВАТЕЛЬ, как в этом примере ниже, ошибка не возникнет ** ошибка произойдет, только если строка.roles(userByLogin.get().getId())здесь нет (значит, применяются новые-старые роли)

      //userConvertedFromHttpRequest - by the name user is created from payload from http request but, set of roles assigned to him is created by seraching roles in DB,
 
    @Transactional
    default User persistByExternalUserId(User userConvertedFromHttpRequest ) {
        final Optional<User> userByLogin = findByLogin(userConvertedFromHttpRequest.getLogin());
        if (userByLogin.isPresent()) {
            User userToSave = user;
            userToSave =  userToSave.toBuilder()
.id(userByLogin.get().getId())                                                                 
.roles(userByLogin.get().getRoles())                                                               
.build();

            return save(userToSave);
        } else {
            return save(userConvertedFromHttpRequest);
        }
    }

0 ответов

Другие вопросы по тегам