Spring中UUID关联实体外键约束失败,TaskCard保存报错
保存TaskCard实体时触发外键约束失败问题
问题描述
保存TaskCard实体时触发MySQL外键约束错误(SQL错误码1452),提示taskcards表的creator_id外键关联users表的id时约束失败。手动使用数据库中存在的UUID关联User插入TaskCard正常,但通过系统认证用户关联时失败。已尝试弃用自定义构造器、打印确认creator对象关联正确,问题仍未解决。
相关代码片段
TaskCard Service
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); }
Controller
@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(); }
User实体
@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; // 省略其他代码 }
TaskCard实体
@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]
已尝试的解决方案
- 弃用自定义构造器,改用常规方式实例化TaskCard对象
- 打印验证creator对象与TaskCard关联的creator对象一致
内容的提问来源于stack exchange,提问作者Luiz Felipe Burgatt Jolo
相关产品推荐
相关产品推荐

