Summary
- 연관관계를 맺는 엔티티간의 요청에서, FK로 쓰는 객체가 아직 저장이 되지 않아 발생하는 오류이다.
- 엔티티의 연관관계가 있을 경우에는 @Cascade 옵션을 설정해준다.
- 연관관계의 FK로 사용할 객체는 새로 생성하지 말고 jpa query를 통해 가져와야 한다.
증상
- User와 @OneToMany 관계인 Authority를 추가하려고 할 때, authority.setUser(user) 부분에서 에러 발생
@Test
void jpaTest2() {
USERTest user = new USERTest();
user.setUsername("test0");
List<AUTHORITYTEST> authorityList = authorityTestRepository.findAuthorityByUserName(user.getUsername());
AUTHORITYTEST authority = new AUTHORITYTEST();
authority.setUser(user); // error !
authority.setUserName(user.getUsername());
authority.setAuthority("ROLE_ADMIN");
authorityTestRepository.save(authority);
}
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException:
object references an unsaved transient instance - save the transient instance before flushing : tom.study.domain.test.AUTHORITYTEST.user
-> tom.study.domain.test.USERTest
원인
- 연관관계를 맺는 엔티티간의 요청에서, FK로 쓰는 객체가 아직 저장이 되지 않아 발생하는 오류.
해결법
- 위 코드에서, User를 새로 만들어서 authority.setUser(user);로 하는 부분이 잘못되었다.
- User를 새로 만드는게 아닌, Jpa 쿼리를 통해 가져와서 setUser에 넣어주면, 저장이 되어있는 객체이기 때문에 에러가 발생하지 않는다.
void jpaTest2() {
USERTest user = userTestRepository.findByUserName("test0").orElseThrow();
List<AUTHORITYTEST> authorityList = authorityTestRepository.findAuthorityByUserName(user.getUsername());
AUTHORITYTEST authority = new AUTHORITYTEST();
authority.setUser(user);
authority.setUserName(user.getUsername());
authority.setAuthority("ROLE_ADMIN");
authorityTestRepository.save(authority);
}
Share article