기존 프로젝트에 새로운 데이터베이스 테이블을 추가하고, 실제 데이터가 제대로 저장되는지 확인하는 코드를 작성한 후에 프로젝트를 실행시켜보니 다음과 같은 예외가 발생하였습니다.
org.hibernate.TransientPropertyValueException:
object references an unsaved transient instance
- save the transient instance before flushing
EntityManager의 persist 함수를 통해 객체를 저장하였는데 해당 객체가 저장되는 과정에서 참조하고 있는 객체가 저장되지 않아 발생한 예외였습니다. 예외를 일으킨 코드는 다음과 같습니다.
WrongQuestion wrongQuestion = WrongQuestion.builder()
.question(new QuestionData(question))
.wrongWorkbook(wrongWorkbook)
.choiceList(question.getChoiceList().stream()
.map(ChoiceData::new)
.collect(Collectors.toList()))
.build();
em.persist(wrongQuestion);
오답 문제집에 오답을 저장하는 코드인데 해당 코드를 persist를 실행할 적에 wrongWorkbook이 데이터베이스에 저장되어 있지 않아 발생한 예외였습니다.
해결 방법은 다음과 같이 2가지가 있습니다.
- cascade를 설정해주어 문제가 저장될 때 문제집이 저장되게 하는 것
- 문제집을 먼저 저장한 후에 문제를 저장하는 것
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class WrongWorkbook extends BaseTimeEntity {
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "wrongWorkbook", cascade = CascadeType.PERSIST)
List<WrongQuestion> wrongQuestionList = new ArrayList<>();
...
}
위와 같이 cascade를 설정해준 후에 em.persisit(wrongWorkbook)을 하게 되면 오답 문제집에 등록되어 있던 wrongQuestion들이 모두 저장되게 됩니다.
두 번째 방법은 코드는 다음과 같습니다.
...
em.persist(wrongWorkbook)
...
em.persist(wrongQuestion);
위와 같이 오답 문제의 문제집을 wrongWorkbook으로 설정하여 저장하기 전에 미리 wrongWorkbook을 저장하게 되면 예외가 발생하지 않습니다.
'🔓 영구 노트' 카테고리의 다른 글
sealed 클래스를 사용하여 else 분기 처리 없애기 (0) | 2022.10.10 |
---|---|
공변성, 무공변성, 반공변성 in kotlin (2) | 2022.10.04 |
if문 중첩 시 간결하게 보이는 법 (0) | 2022.07.06 |
Completed 406 NOT_ACCEPTABLE (0) | 2022.05.27 |
Embedded 사용 시 MappingException 발생 (0) | 2022.04.27 |
댓글