2014-01-27 2 views
1

이제 상태 내 EJB (3.0)의 작업에서 SQLException (시간 초과가 만료 됨)이 발생합니다. 방법은에서 일어난다 :폐기 된 상태 세션 빈 처리 방법

private MyBean myBean; 
@EJB(name = "messageloaderbean") 
public void setMyBean(MyBean myBean) { 
    this.myBean = myBean; 
} 

그리고 그 기준은 호출 클래스 매개 변수로 전달 :

@PersistenceContext(unitName = "MYPU") 
EntityManager entityManager; 

List<Message> list; 

public List<Message> newSearch() { 
    // do some unsignificant things 
    loadFirstPage(); 
} 

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public List<Message> loadFirstPage() { 
    CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
    cq.select(cq.from(entityClass)); 
    list = getEntityManager().createQuery(cq).getResultList(); 
} 

이 SFSB 다른 클래스에 주입 된

public class Controller{ 
    private MyBean myBean; 

    public Controller(MyBean myBean){ 
     this.myBean = myBean; 
    } 
    public void methodThatCallsMyBean(){ 
     this.myBean.newSearch(); 
    } 
} 

무엇 (SQLException과 같은) 런타임 예외가 발생하면 지금 발생합니다. CMT를 사용하고 EJB 사양에 따라 컨테이너가 트랜잭션을 먼저 롤백 한 다음 EJB를 삭제합니다. 그런 다음 폐기 후이 EJB를 다시 사용하려면 javax.ejb.NoSuchEJBException: Bean has been deleted이 표시됩니다.

빈이 삭제되었으므로 의미가 있지만, 새로운 상태의 빈에 대한 참조는 어떻게 얻을 수 있습니까?

대신 SFSB에서 예외를 catch하여이 파기를 방지해야합니까? 예외 상황을 잡으면 트랜잭션의 상태는 어떻습니까? 수동 롤백을해야합니까?

감사합니다.

답변

0

그러나 새로운 상태의 빈에 대한 참조는 어떻게 얻을 수 있습니까?

컨테이너는 Bean 라이프 사이클의 시작 부분에서 프록시를 삽입하므로이 경우 모든 새로운 staless bean 인스턴스는 statefull 참조를 한 번만 주입합니다. JNDI 조회를 통해 참조를 얻을 수도 있지만 더 복잡 할 수 있습니다.

대신 내 SFSB에서 예외를 catch하여이 파기를 방지해야합니까?

예, 이것이 최선의 해결책이라고 생각합니다.

수동 롤백을해야합니까?

예. 컨테이너가 RuntimeException을 가로 채면 Rollback을 위해 Transaction을 표시합니다. 이 동작을 유지하려면 현재 트랜잭션을 수동으로 표시해야합니다.

) a) 응용 프로그램 예외를 throw하고 @AnnotationException (rollback = true)로 주석을 추가하십시오. 이 경우 컨테이너는 bean 인스턴스를 버리지 않고 롤백을 위해 트랜잭션을 표시합니다.

b) SessionContext.setRollbackOnly() 메소드를 통해 트랜잭션을 표시하십시오.

//inject a SessionConetext instance 
@Resource 
SessionContext session; 

try { 
    //your code goes here 
} catch (RuntimeException e) 
//log the error 
    session.setRollbackOnly(); 
{