2012-07-23 2 views
0

중복 된 경우 죄송합니다.엔티티 또는 ID가있는 JPQL @ NamedQuery?

비즈니스 계층에서 ID 대신 개체를 사용하는 것이 가능하거나 권장 할 수 있습니까? 내가 작업하는 방법

SELECT c 
FROM Child AS c 
WHERE c.parent = :parent 
public List<Child> list(final Parent parent) { 

    // does parent must be managed? 
    // how can I know that? 
    // have parent even been persisted? 

    return em.createNamedQuery(...). 
     setParameter("parent", parent); 
} 

이입니다.

SELECT c 
FROM Child AS c 
WHERE c.parent.id = :parent_id 
public List<Child> list(final Parent parent) { 

    // wait! parent.id could be null! 
    // it may haven't been persisted yet! 

    return list(parent.getId()); 
} 

public List<Child> list(final long parentId) { 
    return em.createNamedQuery(...). 
     setParameter("parent_id", parentId); 
} 

업데이트] 질문 --------------------------------------

@EJB으로 각각 주입 할 수있는 JAX-RS 또는 JAX-WS 클래스는 동일한 JTA에서 말할 수 있습니까?

내가 항상 궁금해하는 매우 원래의 문제가 여기에 있습니다.

두 개의 EJB가 있다고 가정 해 보겠습니다.

@Stateless 
class ParentBean { 

    public Parent find(...) { 
    } 
} 

@Stateless 
class ChildBean { 

    public List<Child> list(final Parent parent) { 
    } 

    public List<Child> list(final long parentId) { 
    } 
} 

EJB 클라이언트로 수행하는 적절한 방법은 무엇입니까? 나는 불행하게도 완전히 "두 번째 질문을 이해 어떤 JAX-RS를 수행하지 않기 때문에

@Stateless // <<-- This is mandatory for being injected with @EJB, right? 
@Path("/parents/{parent_id: \\d+}/children") 
class ChildsResource { 

    @GET 
    @Path 
    public Response list(@PathParam("parent_id") final long parentId) { 

     // do i just have to stick to this approach? 
     final List<Child> children1 = childBean.list(parentId); 

     // is this parent managed? 
     // is it ok to pass to other EJB? 
     final Parent parent = parentBean.find(parentId); 

     // is this gonna work? 
     final List<Child> children2 = childBean.list(parent); 

     ... 
    } 

    @EJB 
    private ParentBean parentBean; 

    @EJB 
    private ChildBean childBean; 
} 

답변

1

부모가 아직 보존되지 않은 경우 쿼리가 작동하지 않고 실행하는 것이 의미가 없습니다. 부모가 유지되지 않은 경우 실행하지 않는 것은 사용자의 책임입니다. 하지만 find 메소드 자체에 대해서는 책임을지지 않습니다. 부모가 인수로 전달한 메소드의 문서에서 ID가 있거나 최소한 지속되어야 함을 명확히 밝히십시오. 엔티티 관리자와 동일한 확인을 할 필요가 없습니다.

지속되었지만 플러시가 아직 발생하지 않은 경우 엔티티 관리자는 쿼리를 실행하기 전에 플러시해야하며, 쿼리가 새 상위 항목의 하위 항목을 찾도록해야합니다.

적어도 Hibernate에서는 분리 된 부모와 함께 쿼리를 실행할 수 있습니다. ID가 있으면 쿼리에서이를 사용하고 쿼리를 실행합니다.

2

에만 질문에 대한 답변으로 제시 후,"그것은 불가능하거나 대신 ID의? 객체를 사용하여 비즈니스 계층을 권장합니다 " 또는 @EJB로 각각 주입 할 수있는 JAX-WS 클래스는 같은 JTA에서 말할 수 있습니까? "

가능합니다. 대부분의 경우에도 권장됩니다. ORM의 모든 목적은 우리가 데이터베이스에서의 프리젠 테이션이 아닌 객체와 그 관계에 대해 작동 할 수 있다는 것입니다.

엔티티 ID (특히 대리 ID의 경우)는 종종 저장소 근처에있을 때만 흥미로운 개념입니다. 제공된 퍼시스턴스 만이 id에 접근 할 필요가있을 때, id를 액세스하는 메소드를 protected으로 디자인하는 것이 좋습니다. 그렇게하면 엔티티 사용자에게 소음이 줄어 듭니다.

평소와 같이 유효한 예외도 있습니다. 예를 들어 유선 전체에서 엔티티 전체를 이동하는 것은 너무 많은 자원을 소비하고 엔티티 목록 대신 ids 목록을 갖는 것이 바람직하다는 것을 알 수 있습니다. 문제가 실제로 발생하기 전에 그러한 설계 결정을 내려서는 안됩니다.