2014-03-12 3 views
0

내 서비스 클래스에 아래 코드가있다. 이 코드는 기능의 일부로 두 가지 다른 메소드에서 두 번 호출됩니다. 그것은 처음 첫 번째 방법에서 호출 및 실행org.hibernate.NonUniqueObjectException을주고 데이터베이스에 쓸모없는 객체를 저장하는 Hibernate

 //Some code here... 
     LOG.info("###Inside customer interceptor"); 
     try 
     { 
      customerDao.save(customer); 

     } 
     catch (final Exception exp) 
     { 
     //some code here too... 
     } 

, 나는 바람둥이 콘솔에서 인쇄를 선택 SQL 문이 있음을 볼 수 있지만 예상대로 더 업데이트 SQL 문 (때문에 될 수는 없다 사실은 Hibernate는 즉시 insert/update를하지 않는다). 즉시이 코드 블록을 두 번째 메소드에서 다시 호출하면 Tomcat 콘솔에서 SQL select 문과 SQL 업데이트 문을 볼 수 있으며 그 직후에는 큰 뚱뚱한 org.hibernate.NonUniqueObjectException이 표시됩니다. 내가 이해할 수있는 것은 이전 엔티티가 여전히 세션에 연결되어 있고 DB에 커밋되지 않았기 때문입니다.

그러나 내가 데이터베이스를 볼 때 데이터베이스에 저장된 값은 첫 번째 호출의 개체 였고 두 번째 호출의 개체는 예상 한 것임을 알았습니다. 이게 정상입니까? 아니면 여기에 뭔가 빠졌습니까?

스프링의 주석 (@ 트랜잭션) 기반 트랜잭션 전략을 사용하고 있습니다.

답변

1

이 작업을 수행하려면 .merge(customer) 메서드 또는 .saveOrUpdate(customer) 메서드를 사용하고 싶습니다.

  • 당신이 .merge를 사용하는 경우 당신이 바로 전달 된 하나 세션에있는 개체를 덮어, 당신은 고유하지 않은 예외을받지 않습니다.
  • saveOrUpdate을 수행하는 경우 세션에 업데이트하려는 개체의 인스턴스가 이 아니어야합니다. 그렇지 않으면이 nonUniqueObject 예외가 발생합니다.

spring @Transactional을 사용하고 있기 때문에 전체 트랜잭션을 완료 한 후에 트랜잭션을 커밋해야합니다.

+0

고맙습니다. 제우스. 네, 테스트 목적을 위해 다른 게시물 제안으로 병합() 사용했는데 그것은 오래된 개체 대신 새 개체를 저장하고 nonUniqueObject 예외가 발생하지 않습니다. 그러나 내 질문에 왜 메소드의 실행 종료 후 커밋하지 않은 이유는 메서드 수준에서 @Transactional을 사용하는 이유를 이해하는 것이 더 두 번째 이유는 현재 개체 대신 저장 메서드를 호출하여 데이터 저장소에 저장됩니다 . –

+0

귀하의 질문에 답변하는 방법을 이해해야 할 수도 있습니다. 동일한 세션이 동일한 ID의 두 고객 오브젝트를 갱신하는 데 사용되면 예외가 아닌 고유 한 예외가 발생합니다. 코드의 어딘가에 세션이 닫히지 않으므로 처음으로 저장하면 오류가 발생하지 않으며 두 번째로 세션에 이미 해당 객체가 있으므로 오류가 발생합니다. 또한 저장은 분리 된 객체가 아닌 일시적인 객체를 저장하는 데 사용됩니다. – Zeus

+0

음 ... Hybris 전자 상거래 플랫폼에서이 코드를 사용하고 있습니다.이 코드는이 인터셉터와 관련된 모델에 변경이있을 때마다 트리거되는 인터셉터 클래스 안에 있습니다. 또한 save()가 saveOrUpdate()가 다른 Hibernate 구현에서 수행하는 작업을 수행하는 hibernate의 구현을 사용하고 있습니다. –