2011-01-28 4 views
3

저는 REST 웹 앱을 구축하면서 JPA toplink-essential을 사용하고 있습니다.서블릿 수준에서 OptimisticLockException을 잡는 방법?

하나의 엔티티를 찾고 삭제하는 서블릿이 있습니다.

아래 코드는 서블릿 수준에서 낙관적 인 잠금 예외를 잡을 수 있다고 생각했지만 그렇지 않습니다! 대신 RollbackException이 throw되고 설명서에 다음과 같이 나와 있습니다.

하지만 Netbean IDE GlassFish 로그가 표시되면 어딘가에 optimisticLockException이 발생합니다. 그것은 단지 내 코드에 잡히지 않고있다. (필자의 시스템 인쇄 메시지가 표시되지 않기 때문에 그 안에 들어 가지 않을 것입니다.)

각 패키지 (한 번에 하나씩)를 가져 와서 catch 절로 테스트했지만 두 시간 모두 테스트했습니다. 로그 오류가 "낙관적 인 예외"라고하더라도 캐치 블록에 들어 가지 않습니다.

import javax.persistence.OptimisticLockException; 
import oracle.toplink.essentials.exceptions.OptimisticLockException; 

는 그래서 OptimisticLockException가 발생된다 ?????

@Path("delete") 
@DELETE 
@Consumes("application/json") 
public Object planDelete(String content) { 

    try { 
      EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager(); 

      EntityTransaction txn = em.getTransaction(); 
      txn.begin(); 
      jObj = new JSONObject(content); 
      MyBeany bean = em.find(123); 

      bean.setVersion(Integer.parseInt(12345)); 
      em.remove(bean); 


      //here commit!!!!! 
      em.getTransaction().commit(); 
     } 
     catch(OptimisticLockException e) { //this is not caught here :(
      System.out.pritnln("here"); 
      //EntityTransactionManager.rollback(txn); 
      return HttpStatusHandler.sendConflict(); 
     } 
     catch(RollbackException e) { 
      return HttpStatusHandler.sendConflict(); 
     } 
     catch(Exception e) { 
      return HttpStatusHandler.sendServerError(e); 
     } 
     finally { 
      if(em != null) { 
       em.close(); 
      } 
     } 

오류 메시지 :

[TopLink Warning]: 2011.01.28 05:11:24.007--UnitOfWork(22566987) 
--Exception [TOPLINK-5006] 
(Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException 

    [TopLink Warning]: 2011.02.01 08:50:15.095--UnitOfWork(681660)-- 
javax.persistence.OptimisticLockException: Exception [TOPLINK-5006] (Oracle TopLink 
Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException 

답변

3

확실하지 않지만 javax.persistence.OptimisticLockException (패키지 통지)을 catch하고있을 수 있지만 throw 된 예외는 oracle.toplink.essentials.exceptions.OptimisticLockException이므로 catch되지 않습니다. ? 예외 클래스의 이름이 같더라도 같은 클래스는 아닙니다.

+0

좋은 지적. 위의 코드에서 javax.persistence.OptimisticLockException을 잡았습니다. 나는 oracle.toplink.essentials.exceptions.OptimisticLockException을 잡기 위해 catch 절을 변경했지만 catch하지 않을 때까지 있습니다. 내 게시물에 오류 메시지를 추가했습니다. 그것은 매우 두 가지 유형의 패키지를 보여줍니다. 매우 혼란스러운 –

+0

Ralph가 지적했듯이 예외는 em.getTransaction() 내부에서 던져져 optimisticLockException을 수동으로 잡을 수 없습니다. 유일한 방법은 롤백 예외를 잡는 것이며 "충돌"이 발생했다고 가정합니다. ??? : –

+0

"catch (Exception e)"는 try 블록 내에서 던져진 예외 (체크되지 않았거나 체크 됨)를 잡아야한다. 예외로부터 stacktrace를 얻거나 커밋 라인에 중단 점을 넣고 코드를 단계별로 실행해야한다. 어떻게 볼 수 있습니다. – esaj

2

나는 그것이 em.getTransaction().commit(); 문에 발생합니다 추측 것입니다.

java doc of RollbackExceptio 때문에 해당하면 상기 : EntityTransaction.commit()가 실패 할 때

지속성 제공자에 의해 슬로우.

나는 강력하게 이것이 당신이 정말 라인 bean.setVersion(Integer.parseInt(12345);)에서 (이 때문에 누락의 컴파일되지 않을 것) 사용하는 코드가 아님을 보라,하지만 실제 코드가 같은 문제를 가지고 나는 "희망".

+0

그 오타가 수정되었지만 문제는 아직 두 가지 낙관적 인 잠금 패키지가 발견되지 않습니다. –

0

entityManager.flush()를 호출 해 보았습니까? try/catch 블록 안에 있습니까? JPA가 플러시 될 때 OptimisticLock 예외가 발생합니다.

또한 트랜잭션을 커밋하지 않아도됩니다. 당신은 단순히 txn.commit()을 할 수있었습니다; em.getTransaction(). commit(); 대신.

비슷한 상황에서 javax.persistence.OptimisticLockException을 catch 할 수 있습니다. 제 경우에는 ReST 엔드 포인트를 SSB로 만들고 엔티티 관리자를 삽입했습니다. 그런 다음 다른 SSB의 메소드를 호출하여이 SSB 로직에 대한 컨트롤러 역할을합니다. 이 컨트롤러는 flush()를 수행하고 나머지 끝점/SSB가 catch하고 재 시도하는 OLEX와 rethrows 및 ApplicationException을 잡습니다. 이 패턴을 사용하면 TransactionAttributeType.RequiresNew를 지정하여 OLEX가 이전 트랜잭션을 무효화하기 때문에 새 트랜잭션에서 각 재 시도가 발생하도록해야합니다.