fetch =FetchType.LAZY
cascade =CascadeType.All
에 대해서 알아보자
object references an unsaved transient instance 에러가 떳다
어떻게 해결할건지 뭘 알아야하는지 적어보는 시간이 될 것이다!
FK 로 사용되는 컬럼값이 없는 상태에서 데이터를 넣으려다가 발생한 에러이다.!
내 상황에서는 member 가 없는 상태에서 book에 넣으려다가 발생햇음
해결은 cascade 옵션을 주어서 햇다.
@OneToMany 나 @ManyToOne 에 옵션으로 줄 수 있는 값이다.
Entity의 상태 변화를 전파시키는 옵션
즉 JPA 에서 Cascade 옵션을 사용하면 특정 엔티티를 영속 상태로 만들 때
연관된 엔티티도 함께 영속상태로 만들 수 있다.
member 조회할 때 Team도 함께 조회해야할까?
JPA 에서는 지연로딩 LAZY를 사용해서 프록시로 조회하는 방법으로 해결
이때 어떤 로직에서 Member 조회하면 Team 객체의 클래스에는 Proxy 객체가 조회된다!
여기서는 merge 를 사용할 거다.
public void save(Member member){
if(Member.getId() == null){
em.persist(member);
}
else{
em.merge(member);
}
}
이런식으로 하면 대는데
merge 가 호출되면 우선 해당 엔티티를 1차 캐시에서 먼저 조회한다.
없다면 식별자(id)로 DB에서 엔티티를 검색해 가져와 준영속 상태의 엔티티 값을 대입 받게됨
준영속 상태의 member 자체를 영속성 컨텍스트에 넣는 것은 아니고
merge 는 준영속 객체를 영속하는 것이 아니라.
준영속 객체의 식별자와 일치하는 엔티티를 db에서 가져와 값을 대입받고,
해당 그 엔티티를 반환하는 것이ㅏㄷ.
주의
merge 는 엔티티 모든 필드를 그대로 변경하게됨
엔티티의 일부만 변경하게 되면 나머지는 데이터 잃고 null이 대입된다.
영속성 컨텍스트가 더는 관리하지 않는 엔티티이다.
준영속 상태로 만드는 방법
- em.detach(entity)
- em.clear()
- em.close()
merge는 준영속 상태의 엔티티를 영속상태로 변경할 때 사용하는 기능임.
정리하면