728x90
자세한 코드는 공개 불가 🥹
📌 문제 상황
엔티티를 저장하려고 할 때, 다음과 같은 오류가 발생했다.
org.springframework.dao.DataIntegrityViolationException:
could not execute statement
[Column 'create_dtm' cannot be null]
해당 필드는 엔티티 생성자에서 분명히 설정되었고, 로그에서도 값이 올바르게 출력되고 있었지만, 여전히 DB에선 null 값이 삽입되며 에러가 났다.
❗ 문제 원인
@Transactional 어노테이션이 메서드에 누락되어 있었던 것이 핵심 원인 !!
Spring Data JPA에서는 save()를 호출하면 즉시 DB에 INSERT를 수행하는 것이 아니라, 영속성 컨텍스트에 등록(persist)만 한다.
그리고 flush()는 보통 트랜잭션 커밋 시점에 발생하여 실제 SQL이 실행된다.
하지만 @Transactional이 없으면 Spring은 트랜잭션을 열어주지 않기 때문에, JPA는 save() 호출 직후 즉시 flush()를 실행하게 된다.
이 경우:
- 아직 연관관계(FK)가 완전히 설정되기 전이거나
- 생성자에 설정된 createDtm이 JPA가 보기엔 아직 적용되지 않은 상태라서
➡️ 결국 DB에는 null 값이 삽입되려고 시도되고, NOT NULL 제약 위반 오류가 발생한 것이다.
🧠 배운 점
- JPA의 save()는 즉시 insert가 아닌 영속성 등록일 뿐이다.
- flush는 보통 @Transactional 트랜잭션 커밋 시점에 일어나야 안전하다.
- 트랜잭션 없이 save()를 호출하면 flush의 시점과 저장 SQL 순서가 꼬일 수 있다.
728x90
'오류노트' 카테고리의 다른 글
[오류노트] Git Action 오류 - No such file or repository & Permission denied 403 에러 (0) | 2024.11.17 |
---|---|
[README] IntelliJ에서 README(리드미)파일 수정하기 (0) | 2024.11.03 |
[Swagger 오류] Swagger Whitelabel Error - 404 Not Found 에러 (0) | 2024.11.02 |
[MySQL 오류] ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) (0) | 2024.05.07 |
[Postman 오류] String Boot 404 Not Found 에러 (0) | 2024.05.07 |