2010-03-08 3 views
6

우리는 주입 된 EntityManager를 헬퍼에게 전달하는 JavaEE5 stateless EJB 빈을 가지고있다.주입 된 EntityManager를 EJB 빈의 도우미 클래스에 전달하고 사용하는 것이 괜찮습니까?

안전한가요? 지금까지는 잘 돌아 왔지만 EntityManager의 구현이 스레드로부터 안전하다는 내용의 오라클 문서를 발견했습니다. 지금까지는 우리가 지금까지 문제가 없었던 이유는 단지 우리가 사용하고있는 구현이 thread-safe (Oracle을 사용)이기 때문입니다.

@Stateless 
class SomeBean { 
    @PersistenceContext 
    private EntityManager em; 

    private SomeHelper helper; 

    @PostConstruct 
    public void init(){ 
     helper = new SomeHelper(em); 
    } 

    @Override 
    public void business(){ 
     helper.doSomethingWithEm(); 
    } 

} 

사실은 EntityManager의 스레드 안전하지 않은 경우, 컨테이너가 도우미 클래스로 전파되지 않습니다

inercept business() 
this.em = newEntityManager(); 
business(); 

을해야 할 것입니다 .. 의미가 있습니다.

그렇다면이 상황에서 가장 좋은 방법은 무엇입니까? EntityManager 대신 EntityManagerFactory 전달?

편집 :

편집 : 더 많은 정보를 원하시면이 문제에 관심이 있다면, 당신은 아마 이것도 하나를 체크 아웃 할 수 있도록 This question은 매우 흥미 롭다. ejb3.0 spec

4.7.11 비 재진입 인스턴스 컨테이너는 하나의 스레드 언제든지 인스턴스를 실행할 수 있도록한다. 클라이언트 요청이 인스턴스에 대해 인스턴스가 다른 요청을 실행하는 동안 도착하면 컨테이너가 javax.ejb.ConcurrentAccessException을 두 번째 클라이언트 [24]로 전달할 수 있습니다. EJB를 2.1 클라이언트 뷰를 사용하는 경우, 클라이언트가 원격 클라이언트 또는 에 javax.ejb.EJBException 경우 클라이언트가 로컬 인 경우, 용기는 에 두 번째 요청을 java.rmi.RemoteException을 던질 수있다 클라이언트. [25] 세션 개체는 단일 클라이언트 인 을 지원하기위한 것입니다. 따라서 두 개의 클라이언트가 동일한 세션 개체를 호출하려고 시도하면 응용 프로그램 오류가 발생합니다. 이 함축하는 한 가지 의미는 응용 프로그램 이 세션 bean 인스턴스로 루프백 호출을 할 수 없다는 것입니다.

그리고

4.3.2 의존성 주입 세션 빈이 환경 자원 또는 다른 개체에 대한 참조를 획득하도록 의존성 주입을 메커니즘을 사용할 수있다 이 (제 16 참조 "엔터프라이즈 빈 환경"). 세션 빈은 의존성 주입 사용한다면, 컨테이너는 빈 인스턴스 후이 참조가 생성 입니다 주입하고, 어떤 사업 전에 방법은 콩 인스턴스에서 호출됩니다. SessionContext에 대한 종속성이 선언되거나 bean 클래스가 선택적 SessionBean 인터페이스 (섹션 4.3.5 참조)를 구현하는 경우이 시점에서 SessionContext도 주입됩니다. 종속성 삽입이 실패하면 bean 인스턴스는 이 삭제됩니다. EJB 3.0 API 하에서, 빈 클래스는 SessionBean 인터페이스를 구현하지 않고도 종속성 주입을 통해 SessionContext 인터페이스를 획득 할 수 있습니다. (또는 resource-env-ref 배포 설명자 요소)은 SessionContext에 대한 bean의 종속성을 으로 나타내는 데 사용됩니다. 제 16 장, "엔터프라이즈 빈 환경"을 참조하십시오.

+0

이제는 "EJB 3.1 Spec은 종속성 삽입이 생성시에만 수행되므로 MyRepository의 모든 호출자가 EntityManager의 동일한 인스턴스를 사용하게됩니다." http : //stackoverflow.com/questions/2015184/how-is-threadsafty-guranteed-with-persistencecontext –

+0

참고 자료, § 4.1.13을 읽거나이 응답 http : // stackoverflow를 참조하십시오.co.kr/questions/1954137/how-that-that-instance-pooling-with-ejbs-can-improvement-performance/1954229 # 1954229 따라서 각 도우미는 한 번에 하나의 스레드에 의해 액세스됩니다. – ewernli

+0

이것은 구현하려는 생각과 정확히 일치합니다. 나는 그것이 가능하다는 것을보기 매우 기쁘다. 그레이트 포스트. 감사. – b3bop

답변

2

비슷한 패턴을 사용했지만 도우미가 @PostConstruct에 생성되었으며 삽입 된 엔티티 관리자가 생성자에서 매개 변수로 전달되었습니다. 각 EJB 인스턴스에는 고유 한 도우미가 있었으며 스레드 안전성이 보장되었습니다.

또한 EJB가 완전히 사용되지 않았기 때문에 엔티티 관리자가 삽입되지 않았으므로 도우미는 InitialContext으로 찾아야합니다.

@Stateless 
@PersistenceContext(name="OrderEM") 
public class MySessionBean implements MyInterface { 
    @Resource SessionContext ctx; 
    public void doSomething() { 
    EntityManager em = (EntityManager)ctx.lookup("OrderEM"); 
    ... 
    } 
} 

를하지만합니다 (EJB를 사용하지 않는 경우에도)을 찾아하는 것보다 그것을 주입 실제로 쉽게 :이 경우, 지속성 컨텍스트는 여전히 @PersistenceContext와 부모 EJB에서 "수입"해야 특히 테스트 가능성이 있습니다.

하지만 주된 질문으로 돌아가서, 나는 주입되거나 조회 된 엔티티 관리자가 트랜잭션에 바인딩 된 기본 활성 엔티티 관리자에게 전달하는 래퍼라고 생각합니다.

희망이 있습니다.

편집

3.3 § 부와 약간에게 주제를 커버 사양의 5.6 §.

+0

감사합니다. 생산 코드를 파헤 치지 않아도된다는 소식을 듣게되어 기쁩니다. –

2

나는 도우미에게 방법을 사용하고 거기에 EntityManager을 통과하고 완벽하게 OK입니다했습니다.

그래서 필요할 때마다 메서드에 전달하거나 도우미 자체를 만들고 (@EJB을 사용하여) 주입하고 EntityManager을 삽입하는 것이 좋습니다.

+0

도우미 메서드는 정말 간단하고 좋은 소리입니다. 감사! –

0

개인적으로, 나는 개인 생성자 또는 메소드의 모든 POJO에 Entity Manager를 전달해야한다. 특히 POJO 수가 많은 중요하지 않은 프로그램의 경우.

엔티티 관리자를 직접 사용하는 대신 EntityManager에서 반환 한 엔티티를 처리하는 POJO/HelperClasses를 만들려고합니다.

가능하지 않은 경우 새 EJB Bean을 만들 것이라고 생각합니다.

관련 문제