3

我有一个实体(联系人),它有一个延迟加载的集合。我不知道要更改它,但是当我执行 em.find(Contact.class, myID) 时需要加载集合,这可以在不更改实体且不使用 jpql 语句和 fetch 的情况下完成。?

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>();

}

从我的无状态 bean

@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());
}
4

2 回答 2

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

缺点是这会对数据库进行两次查询:一次获取联系人,另一次获取任务关系。

另一种选择是进行查询,如下所示:

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();

此选项仅进行一次查询。

于 2012-08-31T13:45:54.000 回答
3

您可以结合@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());
于 2012-08-31T14:26:56.757 回答