Ошибка связи объекта с UUID: ограничение внешнего ключа не выполнено. Ява весна

Я пытаюсь сохранить объект TaskCard

Сервис TaskCard:

public TaskCard create(TaskCardCreateData taskCardCreateData) {
    var creator = authenticatedUserService.getAuthenticatedUser();
    var taskCard = new TaskCard(
            taskCardCreateData.title(),
            taskCardCreateData.description(),
            taskCardCreateData.dueDate(),
            creator,
            taskCardCreateData.priority()
    );
    return taskCardRepository.save(taskCard);
}

Контроллер:

@PostMapping @Transactional public ResponseEntity createTaskCard(@RequestBody @Valid TaskCardCreateData taskCardCreateData, UriComponentsBuilder uriComponentsBuilder){

    var taskCard = taskCardService.create(taskCardCreateData);
    var uri = uriComponentsBuilder.path("/taskcard/{id}").buildAndExpand(taskCard.getId()).toUri();

    return ResponseEntity.created(uri).body(new TaskCardDetailData(taskCard));
}

Аутентифицированный сервис получения пользователей:

public User getAuthenticatedUser() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    return (User) authentication.getPrincipal();
}

Пользователь сущности:

@Table(name = "users")
@Entity(name = "User")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;

    private String login;
    private String password;

    @OneToMany(mappedBy = "creator")
    private Set<TaskCard> taskCards;
...
}

Карта задач сущности:

@Table(name = "taskcards") @Entity(name = "TaskCard") public class TaskCard {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String description;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
private LocalDateTime dueDate;

@ManyToOne
@JoinColumn(name = "creator_id")
private User creator;

public TaskCard() {
}

public TaskCard(String title, String description, LocalDateTime dueDate, User creator, String priority) {
    this.title = title;
    this.description = description;
    this.createdDate = LocalDateTime.now();
    this.dueDate = dueDate;
    this.creator = creator;
    this.priority = priority;
    this.status = TaskCardStatus.BACKLOG;
    this.active = true;
}...`

Ошибка:

Hibernate: insert into taskcards (active, created_date, creator_id, description, due_date, priority, status, title, updated_date) values         (?, ?, ?, ?, ?, ?, ?, ?, ?) 
2024-08-27T22:44:36.744-04:00  WARN 35454 --- \[todolu\] \[nio-8080-exec-1\] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1452, SQLState: 23000 2024-08-27T22:44:36.744-04:00 ERROR 35454 --- \[todolu\] \[nio-8080-exec-1\] o.h.engine.jdbc.spi.SqlExceptionHelper   : Cannot add or update a child row: a foreign key constraint fails (todolu.taskcards, CONSTRAINT fk_taskcards_users FOREIGN KEY (creator_id) REFERENCES users (id) ON DELETE CASCADE) 2024-08-27T22:44:36.756-04:00 ERROR 35454 --- \[todolu\] \[nio-8080-exec-1\] o.a.c.c.C.\[.\[.\[/\].\[dispatcherServlet\]    : Servlet.service() for servlet \[dispatcherServlet\] in context with path \[\] threw exception \[Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement \[Cannot add or update a child row: a foreign key constraint fails (todolu.taskcards, CONSTRAINT fk_taskcards_users FOREIGN KEY (creator_id) REFERENCES users (id\`) ON DELETE CASCADE)\] \[insert into taskcards (active,created_date,creator_id,description,due_date,priority,status,title,updated_date) values (?,?,?,?,?,?,?,?,?)\]; SQL \[insert into taskcards (active,created_date,creator_id,description,due_date,priority,status,title,updated_date) values (?,?,?,?,?,?,?,?,?)\]; constraint \[null\]\] with root cause

java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (todolu.taskcards, CONSTRAINT fk_taskcards_users FOREIGN KEY (creator_id) REFERENCES users (id) ON DELETE CASCADE)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118) \~\[mysql-connector-j-8.3.0.jar:8.3.0\]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) \~\[mysql-connector-j-8.3.0.jar:8.3.0\]

в базе данных все происходит нормально, успех при вставке карт задач с действительными пользователями UUID и ошибка при вставке недействительных карт задач

Я уже пытался создать экземпляр и установить объект карты задач традиционным способом, не используя созданный собственный конструктор.

Печать переменных

пример обслуживания этой печати:

public TaskCard create(TaskCardCreateData taskCardCreateData) {    
var creator = authenticatedUserService.getAuthenticatedUser();
    System.out.println("CREATOR");
    var teste = creator.toString();
    System.out.println(teste);
    var taskCard = new TaskCard(
            taskCardCreateData.title(),
            taskCardCreateData.description(),
            taskCardCreateData.dueDate(),
            creator,
            taskCardCreateData.priority()
    );
    System.out.println("TASKCARD CREATOR");
    var testedois = taskCard.getCreator().toString();
    System.out.println(testedois);
    return taskCardRepository.save(taskCard);
}

CREATOR User{id=66386333-6465-3364-2d31-6665612d3464, login='luiz.jolo', password='$2a$12$FohqZ/qawqsrlhmFH0zoE.SoviWTjKN18Qyi6EnBcfZjm5qLbBn9y'} TASKCARD CREATOR User{id=66386333-6465-3364-2d31-6665612d3464, login='luiz.jolo', password='$2a$12$FohqZ/qawqsrlhmFH0zoE.SoviWTjKN18Qyi6EnBcfZjm5qLbBn9y'} Тот же объект!

Что authenticatedUserService.getAuthenticatedUser() возвращает?

talex 28.08.2024 07:41

@talex Автор упомянул в описании, когда он пытается распечатать объект-создатель, ответ => User{id=66386333-6465-3364-2d31-6665612d3464, login='luiz.jolo', пароль='$2a$12$FohqZ /qawqsrlhmFH0zoE.SoviWTjKN18Qyi6EnBcfZ‌​jm5qLbBn9y'}

SamPaul Isaac 28.08.2024 07:51

Этот объект получен из БД или создан каким-то другим способом?

talex 28.08.2024 07:53

Можете ли вы рассказать об этом подробнее: «успех при вставке карт задач с действительными пользователями UUID и ошибка при вставке недействительных карт задач»?

talex 28.08.2024 07:56

@talex На основе кода, упомянутого в описании, он извлекает данные пользователя из уже загруженного объекта аутентификации, хранящегося в памяти, а не из БД.

SamPaul Isaac 28.08.2024 07:56

@SamPaulIsaac Похоже, мне нужны новые очки :) но это объясняет проблему. Нам нужно увидеть, кто установил принципал в объекте Authentication. Похоже, это исходит не от БД.

talex 28.08.2024 07:59

@talex «Нам нужно посмотреть, кто установил принципала в объекте аутентификации». - Я согласен.

SamPaul Isaac 28.08.2024 08:02

Кроме того, нам необходимо ПРОВЕРИТЬ, что таблица пользователей содержит пользователя с идентификатором, который соответствует идентификатору Creator_id, вставленному в таблицу Taskcards.

SamPaul Isaac 28.08.2024 08:03

Я согласен, что, скорее всего, пользователь не был сохранен в базе данных до того, как попытался сохранить карточку задачи, поэтому ограничение не может быть удовлетворено. Вы можете попробовать каскадное сохранение, но если вы не убедитесь, что каждый пользователь имеет уникальный идентификатор, вы рискуете получить несколько объектов для одного и того же пользователя. Следовательно, лучше убедиться, что пользователь хранится в БД, и получить правильный идентификатор при загрузке принципала.

Thomas 28.08.2024 08:12

Упомянутый случай успеха и ошибки относится к добавлению «карт задач» непосредственно с кодом SQL в базу данных. Если я попытаюсь добавить «карту задач» с несуществующим или недействительным UUID, банк не разрешит это. В базе данных есть пользователь с UUID, упомянутым в коде, поскольку он нормально аутентифицируется и получает ключ JWT, и поэтому я могу зафиксировать это в «getAuthenticatedUser».

Luiz Felipe Burgatt Jolo 28.08.2024 16:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
10
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема решена! Это моя неудача в момент создания таблиц базы данных с пролетными миграциями, это тип идентификатора, я использовал VARCHAR (36), а теперь меняю на BINARY (16), пользовательскую таблицу и карты задач, и проблема решена. Я должен был опубликовать схему.

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