2013-05-13 2 views
0

여기에 아주 이상한 상황이 있습니다. 엔티티 집합을 삭제하려고하면 즉시 같은 요소가있을 수도 있고 없을 수도있는 엔티티 집합을 추가하려고하면 아래 예외가 발생하는 것 같습니다. 그다지 말하지 않기 때문에 전체 스택 추적은 필요하지 않습니다.JPA/Hibernate EntityNotFoundException 해결

javax.persistence.EntityNotFoundException: deleted entity passed to persist [com.test.MyEntity#<null>] 

좀 더 명확하게하기 위해 좀 더 자세한 설명을하겠습니다.

이것은 내 단체입니다.

@Entity 
@Table(name = "MY_ENTITY") 
@SequenceGenerator(name = "my_enty_seq", sequenceName = "MY_ENTITY_SEQ") 
public class MyEntity { 

    private long id; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_enty_seq") 
    @Column(name = "ID", unique = true, nullable = false, precision = 12, scale = 0) 
    public long getId() { 
     return this.id; 
    } 

    // Other methods & variables which are not relevant here. 
} 

그리고 이것은 엔티티와 함께 ​​연주하는 클래스입니다.

public class MyEntityServiceImpl implements MyEntityService { 

    public void updateMyEntities(List<MyEntity> newEntities) { 

     // Delete the Old Items 
     List<MyEntity> oldEntities = myDAO.getAllEntities(); 
     myDAO.delete(oldEntities); // myDAO extends GenericDaoJpaWithoutJpaTemplate, hence, the DELETE is available in it. 

     // Add the New Items 
     myDAO.store(newEntities); // This is where I get the mentioned Exception. 
    } 

    // Other non-relevant stuffs 
} 

나는 store() 방법에 언급 된 예외를 얻는의 시나리오 oldEntitiesnewEntities 목록 모두에 존재하는 몇 가지 일반적인 MyEntity 객체가있을 때입니다.

나는이 작업을하기 위해 많은 노력을했지만 아무 것도 문제를 극복하는 데 도움이되지 않습니다. 덧붙여서 FetchType.EAGER & CascaseType.ALL, CascaseType.PERSIST도 작동하지 않았습니다. EntityManager은 메서드가없는 것 같습니다. 메서드보다 먼저 사용할 수 있습니다. 나는 persist()으로 store()을 교환하려고 시도했다 (내부적으로 상점에 저장한다).

참고 : - 참고 사항 : 이전 목록을 삭제하고 새로운 목록을 삽입하는 것은 요소를 비교하고 새 목록 만 추가하는 작업이 지루한 경우입니다 (목록이 꽤 거대 할 수 있음).

답변

0

나는 이것을위한 방법을 알아 냈습니다. flush() 메서드 대신 flushAndClear() 메서드를 사용했습니다.

flush()은 지속성 캐시를 DB와 동기화했지만 캐시를 지우지 않은 것으로 보입니다. 한편, 보류중인 모든 작업을 수행 한 다음 모든 작업을 지 웁니다. 삭제 방법에 대한 org.crank.crud.GenericDao<T, PK extends Serializable>의 소스 코드에 존재하는 자바 문서에서 인용

,

하면 데이터베이스에 영구 저장소에서 개체를 제거합니다.이 이 PK를 사용하여 삭제를 수행하기 때문에, id 1을 사용하여 개체를 삭제하지만 해당 개체가 여전히 엔티티 관리자 캐시에있는 경우 엔티티 관리자 이 일관성없는 상태로 남아있을 수 있습니다.

두 가지 작업을 수행 할 수 있습니다. 모든 PK 삭제를 한꺼번에 처리 한 다음 flushAndClear를 호출하거나이 문제가 발생하지 않는 개체 인 으로 삭제 방법을 호출하면됩니다.

flushAndClear() 메서드를 사용하여 첫 번째 옵션을 시도하고 예상대로 작동했습니다.

2

저는 예외라고 생각합니다. 세션에서 엔티티 X를 삭제하고 동시에 엔티티 X를 저장하도록 요청했습니다. 이제는 가난한 부분이 혼란스럽고 무엇을해야할지 모릅니다.

새/이전/삭제 된 항목을 유지하기 전에 commit을 통해 Session.flush()을 수행 할 수 있습니다.

편집 :이 트릭을하지 않는 경우

, 당신은 새로운 세션에 삽입 할 필요가있다. 임시 엔티티가 없지만 실제로 삭제 된 문제 일 수 있습니다. 따라서 모든 데이터를 새로운 인스턴스로 복사해야 할 수도 있습니다.

+0

커밋은 트랜잭션의 실제 커밋 전에 플러시를 수행합니다. –