관리 메뉴

HeBhy, since 1983.

Java- detached entity passed to persist 관련 문제 해결에 대해. 본문

Dev/Web

Java- detached entity passed to persist 관련 문제 해결에 대해.

HeBhy 2020. 6. 12. 16:29

@OneToMany 같은 1:n 관계에서.. 보통 위 검색어로 검색을 하면.. 추천답변이 CascadeType.ALL 이나 CascadeType.PERSIST 를 지우고 CascadeType.MERGE로 사용하라는 내용이 많습니다. (@ManyToOne같은 경우는 MERGE만 써도 무방합니다.)

 

하지만, 근본적인 문제해결이 될 수 없는 경우가 있는데, 바로 "orphanRemoval = true" 속성이 있는 경우입니다.

 

예를 들어, 게시판에 파일을 첨부하게 될 경우, 새 게시물에 PERSIST 속성이 없다면 파일첨부를 위해 추가 코드를 작성해야 할지도 모릅니다. (부모엔티티 save시 하위엔티티가 자동으로 PERSIST되지 않으므로 파일첨부가 안된다. -> 글 수정시에는 정상으로 파일첨부됨)

 

만일, orphanRemoval = true를 쓰지 않는다면 일일이 파일 변경내용을 확인해서 갱신처리를 해줘야 합니다.

하지만, PERSIST속성과 orphanRemoval = true를 쓰면 고민할 필요가 없는데.. 보통 게시물 수정 처리시에 "detached entity passed to persist" 문제가 발생합니다.

 

즉, JPA repository를 사용하여 수정 대상 게시물을 체크하기 위해 article= bbsRepo.findByIDAnd...(id_article) 를 사용했다고 하면, 반드시 읽어온 후에 detach를 시켜야 합니다. 즉, 기존에 persist된 entity중에 충돌되는것이 있기때문에 위 에러가 뜨는 것입니다.(기존 persist된 entity의 자식entity중에 변경사항이 있는데, 변경사항이 아직 저장되지 않고 새로 자식객체를 select할 경우 상이한 persist가 충돌하기 때문입니다..) 즉, article이라는 엔티티의 자식인 List<BBSFile> 엔티티를 clear 시켜버리고 새로 파일List를 갱신한 후, file을 검증하기 위해 fileRepo.findByFileID...(id_file)한다면 위와 같은 에러가 뜰 것입니다.

 

해결법은.. 서비스 클래스에

@PersistenceContext private EntityManager em;

 

를 추가하고, 함수안에서 em.detach(entity); 를 하면 해결이 됩니다.

 

 

 

참고로, 트랜젝션이 종료되고 entity를 반환할 떄, stack overflow와 관련한 오류와 관련해서도 트랜젝션 종료 전 em.detach(result entity)나 em.clear()을 하면 해결될 수도 있습니다.(무한참조 방지)

Comments