2009-09-06 1 views
4

이것은 디자인 패턴 질문입니다. 다음은 시나리오입니다. JPA에서 EJB3.0을 사용하고 있습니다. 예를 들어 그룹에 속할 수있는 사용자가 있다고 가정 해 보겠습니다. 그래서 내 User 엔티티에서 getGroups() 메서드를 사용하여 그룹을 느리게 가져옵니다. 그리고 나는 방법을 가지고 무 상태 세션 빈 인 UserDao이
사용자 인 getUser (INT의 UID) 내 JSF의 백업 빈에서 이제JPA, EJB 및 JSF 관리 Bean을 결합하는 데 선호되는 디자인 패턴은 무엇입니까?

내가 UserDao의 원격 인터페이스를 주입하고 얻을 그것에 인 getUser를 호출 사용자 bean. 하지만 detached 엔티티이기 때문에 user.getGroups에 액세스 할 수 없습니다. 그래서 여기에 세 가지 접근 방식을 생각할 수 있습니다 :

  1. 내 DAO 방법에서는 열심히 또한 원격 User 엔터티에서 액세스 할 수 있도록 그룹도 가져옵니다. 그러나이 문제는 그룹 자체가 느슨하게 가져온 관계를 가질 수 있으며 또한 열심히 가져와야 할 것이고 더 편한 관계를 갖는 등의 문제가있을 수 있습니다. 그래서 나는 내가 필요로하지 않을 재산의 대부분을 무거운 체중 물건으로 보내 게 될 것입니다.
  2. 나는 사용자를있는 그대로 보내며 내 클라이언트에 의존하여 getGroups를 호출하지 않습니다. 나는
    목록 < 정수 > getGroupsIds (INT 사용자 ID)
    입니다 userdao에 별도의 방법을 제공 할 수 있습니다 그리고 나는 유사한 방법을 가지고 GroupDao getGroup (INT의 groupId)와 다른 방법이 게으른 관계의 ID를 얻을 수 있습니다.

  3. 세 번째 옵션은 이러한 JPA 엔티티를 전혀 전송하지 않고 각 엔티티의 기본 속성 만 포함하는 UserInfo, GroupInfo 등의 다른 POJO를 작성하여 전송하는 것입니다.
    목록 <GROUPINFO> getGroupsForUser (INT의 UID)
    목록 < 사용자 정보 > getUsersInGroup (INT의 GID) 그래서

: 그리고 같은 다른 관계에 대한 이러한 개체를 얻을 수의 DAO의 메소드를 가질 수 있습니다 이 중 어느 것이 바람직한 패턴인지를 결정합니다. 아니면 사람들이 여기에서 사용하는 다른 패턴이 있습니까?

+3

이들을 원활하게 통합하는 가장 쉬운 방법은 Seam을 사용하는 것입니다. http://www.jboss.com/products/seam/ – skaffman

+0

그래, 제가 가장 좋은 방법이 될 수있는 Seam에 대해 조금은 알지만, Seam을 사용하지 않고 붙어 있습니다. –

+0

특정 JPA 구현에 있는지 또는 일반적으로 묻는 중입니다. EclipseLink & Kodo는 필요에 따라이를로드합니다. 또는 개발자가 열렬한 가져 오기를 요청할 수 있습니다. –

답변

0

내 현재 프로젝트에서 세 번째 옵션이 이미 구현되어 있습니다. 이거는 좋지 않습니다. 매번 2-3 수업을 변경해야합니다. 필드가 중복되는 식입니다. 옵션이 아닙니다.

두 번째 옵션보다 User 오브젝트가 열심히 가져올 수있는 모든 정보가 실제로 필요하지 않은 경우.

실제로 모든 사용자 정보가 필요하다는 사실이 밝혀지면. 그리고 아무도 원격 서비스를 통해 User 객체를 사용한 다음 User 객체를 사용하십시오.

어딘가에 다른 해결책이 있습니다. 나는 더 나은 것을 원한다.

4) 관련 API 호출, 예를 들어,에 "인플레이션 수준"매개 변수를 포함 :-)

+0

두 번째 접근법의 문제점은 고객에게 적절한 호출을하기 위해 위험하다는 것입니다. 클라이언트는 getGroups를 호출하지 않아도된다는 것을 알지 못합니다. –

+0

public 액세스에서 getGroups()를 제거하십시오. –

+0

JPA (최대 절전 모드)가 붙어있는 곳이라고 생각합니다. 멋지지만 실제로는 멋진 기능을 사용할 수 없습니다. –

1

도 4, 5 가지 옵션이 있습니다 getUser (id, inflationLevel). 따라서 와이어를 통해 전송 된 객체의 어떤 부분이 해당 객체를 사용할 클라이언트에서 사용 가능한지 선택하는 책임을 위임하게됩니다. 원하는대로 초대 레벨을 거칠거나 미세하게 말할 수 있습니다.일반적인 예는 BASIC (즉각적인 속성 만 채워짐), ASSOCIATIONS (기본 + 직접 수집/연관), FULL (전체 계층 - 모든 연관된 객체)과 같은 것입니다.

5) 당신은 over-the-wire 지연 초기화를 지원할 당신 자신의 프록시를 작성할 수 있습니다. 이 방법은 게으른로드하는 관련 객체 (또는 속성)가 잠재적으로 거대 할 수 있지만 비교적 드물게 (클라이언트별로) 사용되는 경우에만 가능합니다. 사용자 인스턴스가 분리되는 이유는 skaffman이

0

:-) 언급 한 바와 같이

그리고, 물론,이 Seam의? JPA를 실제로 사용하는 경우 살아있는 인스턴스를 사용할 수 있습니다. 따라서 getGroups()이 호출 될 때 사용자 그룹이 느리게로드됩니다.

+0

EJB 컨테이너 관리 트랜잭션에서 EJB 메소드를 종료 할 때 트랜잭션이 종료되므로 영구 컨텍스트가 파기되고 트랜잭션이 관리하는 모든 엔티티가 분리되므로 트랜잭션이 분리됩니다. –

+0

다릅니다. 문서의 작은 인용 부분 : "Java EE 환경에서 jta-data-source 및 non-jta-data-source 요소는 으로 사용되어 JTA 및/또는 비 JTA 데이터 소스의 전역 JNDI 이름을 지속성 공급자 에 의해 사용됩니다. " –

관련 문제