我有一个实体(Contact),它有一个延迟加载的集合。我没有改变这个但是我需要在我执行em.find(Contact.class,myID)时加载集合,这可以在不更改实体且不使用带有fetch的jpql语句的情况下完成。 ?
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>();
}
来自我的无状态豆
@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());
}
答案 0 :(得分:6)
Contact entity = em.find(Contact.class, mappedContact.getContact());
entity.getTaskRelations().size(); // this will fetch the TaskRelations
return entity;
缺点是这会向数据库发出两个查询:一个用于获取联系人,另一个用于获取TaskRelations。
另一个选择是创建一个Query,如下所示:
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();
此选项仅进行一次查询。
答案 1 :(得分: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());