I have an entity (Contact) that has a collection that is lazy loaded. I do not which to change this but i need to load the collection when i do a em.find(Contact.class, myID) can this be done without changing the entity and without using jpql statement with 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>();
}
From my statless 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());
}
Contact entity = em.find(Contact.class, mappedContact.getContact());
entity.getTaskRelations().size(); // this will fetch the TaskRelations
return entity;
The downside is that this makes two queries to the database: one to get the Contact, and another one to fetch the TaskRelations.
Another option is to make a Query, like this:
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();
This option makes only one query.
You can combine @arthuro's solution and reflection to invoke all getters. Something like this:
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;
}
And then invoke it like this:
Contact entity = findEager(em, Contact.class, mappedContact.getContact());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With