2013-06-03 6 views
21

를 작동하지 않는 개체를 제거 나는 일반적으로 잘 작동합니다 다음 코드가이 그냥 작동 내 엔티티 클래스의 많은JPA/최대 절전 모드는 가끔

public void delete(T object) 
{ 
    EntityManager em = getPersistence().createEntityManager(); 
    EntityTransaction et = em.getTransaction(); 
    try 
    { 
    et.begin(); 
    object = em.find(object.getClass(), object.getId()); 
    em.remove(object); 
    em.flush(); 
    et.commit(); 
    } 
    catch(Exception e) 
    { 
    error("Unable to delete " + object.toString() + ": there are references to it."); 
    } 
    finally 
    { 
    if (et.isActive()) et.rollback(); 
    em.close(); 
    } 
} 

합니다. 그러나 그것들 중 2 개는 아무 것도하지 않으며, 예외를 던지지도 않으며 객체를 삭제하지 않습니다. hibernate로부터의 로그는 hibernate가 다수의 select 질의들을 수행하지만 그것은 delete를 실행하려고 시도하지 않는다는 것을 보여준다.

이미 다른 유사한 질문 herehere에서 발견 제안을 시도했지만, 아무 소용 (물론, 후자는 내가 사용할 수 없습니다 @Transactional을 제안하지만, 난 그냥 대신 begin()commit() 사이의 문을 동봉).

나는이 두 클래스가 다른 것보다 많거나 적은 것을 찾을 수없는 것 같습니다. 그들은 내가 가지고있는 거의 모든 다른 엔티티처럼 @PrimaryKeyJoinColumn을 사용합니다. 그들은 ohters처럼 @OneToMany@ManyToOne을 가지고 있습니다. 솔직히 말해서 그들은 다른 클래스를 참조하는 다른 클래스를 참조하는 @OneToOne(optional = false) 필드를 가지고 있지만 다른 엔티티는 가지고 있지 않지만 필드를 변경할 수 있다고 말하지 않으면 (그리고 결과적으로 데이터베이스 스키마를 변경하는) 번거로운 과정을 거치지는 않을 것입니다. 그 이유.

@OneToOne은 무엇입니까? 아니면 내 삭제 코드 도청입니까?

+0

cascade.ALL과 orphanRemoval = true를 추가하려고 시도 했습니까? – willome

+0

@willome : 그것은 정반대의 문제였습니다. "너무 많이"계단식으로 연결되어있었습니다. 아래의 Steve Ebersole의 대답을 참조하십시오. –

답변

58

이 그래프에서 지속성을 삭제중인 것으로 다시 연결시키는 관계가 있습니까? 그렇다면, JPA 스펙은 공급자가 그러한 경우에 삭제를 취소 할 것임을 분명히 명시합니다. 이 경우, Hibernate는 "un-scheduling entity deletion [...]"이라는 로그 문을 작성한다. 로커 org.hibernate.event.internal.DefaultPersistEventListener에서 추적 로깅을 사용하면이를 볼 수 있습니다.

이런 경우 JPA 사양에서 요구하는대로 이러한 연결을 정리해야합니다.

+0

그게 문제 였어, 고마워! –

+0

예를 들어 Persist에 CascadeType이 필요한 경우 소유자 측에 주석을 추가해야합니까? – Sergio

+4

캐스케이드가 지속되도록하려면 그곳에 둘 수 있습니다. 엔티티를 삭제하기 전에 부모 목록에서 코드를 제거하고 부모를 null로 설정해야합니다. – Rian

18

을 으로 바꾸면 @OneToMany 연관이 예상되는 결과를 얻습니다. 상위 레코드를 삭제할 필요없이 하위 레코드가 올바르게 제거됩니다.

오류가 더 명확하게 기록되지 않습니다.

+1

이것은 부모가 삭제에 대한 책임이있는 경우에 유용합니다. 그러나 자식이 삭제에 대한 책임이있는 경우 부모에서 요소를 제거 (참조 파기) 한 다음 자식을 삭제하여 수행 할 수 있습니다. – Thomas

4

나는 함께 모인 것들을 따라 할 때 같은 문제가 발생했습니다. 어린이없이 참조

  1. 절전 3.6.10.Final
  2. 모회사.
  3. 부모를 참조하는 일부 하위 항목입니다. 레거시 코드입니다.

    class ChildEntity { 
        @ManyToOne(cascade = CascadeType.ALL) 
        private ParentEntity parent; 
    } 
    
  4. 아이 엔티티는 세션 컨텍스트에로드 한 후 트랜잭션 내에서 JPA 알림 (저장 프로 시저, 네이티브 SQL)

  5. 는 그런 부모가 삭제할 수 없습니다 않고 테이블에서 제거됩니다. TRACE 로그에서 삭제, 예외 없음, '예약 취소'메시지 만.

해결책 : 캐스케이드 속성을 제거했습니다. 어떤 하위 엔티티가 상위 삭제를 차단하는지 찾기가 다소 어려웠습니다.또한 부모 엔티티를 제거하면 왜 하위 계단식이 영향을 미치는지 이해할 수 없습니다.