2012-08-31 4 views
3

지연로드 된 콜렉션을 가진 엔티티 (연락처)가 있습니다. 나는 이것을 변경하지 않지만 컬렉션을로드해야 할 때 em.find (Contact.class, myID)를 수행하면 엔티티를 변경하지 않고 가져올 수있는 jpql 문을 사용하지 않고도이 작업을 수행 할 수 있습니다. ? 하나는 연락을 얻기 위해, 또 다른 하나는 TaskRelations를 가져 :이 데이터베이스에 두 개의 쿼리를 만드는 것을 내 statless 콩entitymanager를 사용하여 열심히 컬렉션을로드하십시오.

@PersistenceContext(unitName="myContext") 
private EntityManager em; 

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
private Contact getContact(ContactMapping mappedContact){ 
    //force em to load the collection of taskRelations 
    return em.find(Contact .class, mappedContact.getContact()); 
} 

답변

2

@ arthuro의 솔루션과 리플렉션을 결합하여 모든 getter를 호출 할 수 있습니다. 이런 식으로 뭔가 :이 같은

public static <T> T findEager(EntityManager em, Class<T> type, Object id) { 
    T entity = em.find(type, id); 
    for (Field field: type.getDeclaredFields()) { 
     OneToMany annotation = field.getAnnotation(OneToMany.class); 
     if (annotation != null) { 
      if (annotation.fetch().equals(FetchType.LAZY)) { 
       try { 
        new PropertyDescriptor(field.getName(), type).getReadMethod().invoke(entity); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
    return entity; 
} 

그리고 그것을 호출 :

Contact entity = findEager(em, Contact.class, mappedContact.getContact()); 
5
Contact entity = em.find(Contact.class, mappedContact.getContact()); 
entity.getTaskRelations().size(); // this will fetch the TaskRelations 
return entity; 

단점에서

public class Contact implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name="contactId", nullable=false) 
    public String contactId;  

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "contact", orphanRemoval = true, fetch=FetchType.LAZY) 
    private List<ContactTaskRelation> taskRelations = new ArrayList<ContactTaskRelation>(); 

} 

이다.

또 다른 옵션은 다음과 같이 쿼리를 만드는 것입니다 :

String queryString = "SELECT model FORM Contact model JOIN FETCH model.taskRelations WHERE model.id = :id"; 
Query query = em.createQuery(queryString); 
query.setParameter("id", mappedContact.getContact()); 
return query.getSingleResult(); // or getResultList(); 

이 옵션은 하나의 쿼리를합니다.

+0

그래 난 당신의 첫 번째 옵션을 고려하지만,하지만 나는 모든 컬렉션을 알고 앞으로 더 추가 될 것을 요구한다 엔티티와 나는 또한 콩 메소드를 업데이트해야한다. 그래서 나는 정말로 그걸로 갈 수 없어. 두 번째 문제는 똑같은 문제가있을 것입니다. 실제로 컬렉션이있는 엔티티가 많이 있습니다. 이는 단순한 예제 일뿐입니다. 시도해 줘서 고마워. =) – Marthin

관련 문제