작성
·
36
0
아래 코드에서 em.flush()와 em.clear()를 사용하면 findChild가 삭제되는데 em.flush()와 em.clear()를 사용하지 않으면 findChild가 삭제되지 않는 이유에 대해서 잘 모르겠습니다.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
//code
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Child child1 = new Child();
Child child2 = new Child();
Parent parent = new Parent();
parent.addChild(child1);
parent.addChild(child2);
em.persist(parent);
// flush, clear 사용 여부에 따라 remove가 안됨
em.flush();
em.clear();
Child findChild = em.find(Child.class, 1L);
System.out.println("findChild.getId() = " + findChild.getId());
em.remove(findChild);
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
// 연관관계 편의 메서드
public void addChild(Child child){
childList.add(child);
child.setParent(this);
}
}
@Entity
public class Child {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
}
답변 2
0
안녕하세요. kshlove735님
다음을 참고해주세요.
https://www.inflearn.com/community/questions/56718
참고로 실무에서는 잘 발생하지 않는 상황이기 때문에 너무 고민하지 않으셔도 괜찮습니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
이 문제는 JPA의 영속성 컨텍스트와 관련이 있습니다. 먼저 em.flush()
와 em.clear()
가 하는 일을 이해할 필요가 있습니다:
em.flush()
는 영속성 컨텍스트의 변경 사항을 데이터베이스에 즉시 반영합니다. 그러므로 flush()
호출 후에는 데이터베이스와 영속성 컨텍스트 사이의 상태가 일치하게 됩니다.em.clear()
는 영속성 컨텍스트를 초기화합니다. 따라서 모든 영속성 엔티티가 준영속 상태가 됩니다.질문에서 코드를 보면, flush()
와 clear()
호출을 통해 모든 변경 사항을 데이터베이스에 반영하고, 영속성 컨텍스트를 초기화하여 새로운 컨텍스트가 됩니다. 이 상태에서 find
메서드를 호출하면 데이터베이스에서 새로 엔티티를 조회합니다. 그런 다음 remove
를 호출하면 정말로 데이터베이스에서 해당 엔티티가 삭제됩니다.
그러나 flush()
와 clear()
를 사용하지 않으면, find
메서드는 영속성 컨텍스트를 통해 이미 존재하는 엔티티를 찾습니다. 이 때는 remove
가 데이터베이스에 변경 사항을 반영하기 전에, 다른 뭔가가 이 엔티티에 의존하고 있거나 변경이 필요할 수도 있는 상태로 남아있을 수 있습니다.
해결책 요약:
- flush()
와 clear()
를 사용하여 영속성 컨텍스트의 상태를 명확히 관리하세요.
- 또는, em.remove()
를 호출하기 전에 em.find()
로 조회한 엔티티가 영속성 컨텍스트 내에서 어떤 상태인지를 확인해야 합니다.
다음의 기존 Q&A를 참고하시기 바랍니다:
- 왜 delete 쿼리가 안나가는 걸까요?
- CascadeType.ALL로 부모나 자식을 remove할 때 질문입니다
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.