In my web application, I load many objects to display them in a table. I can click on each scoreboard to get "detailed information" regarding a particular entity.
It was obvious to me not to download "detailed information" to view the table, but only when someone wants to see it (clicks a row).
It’s just that the setting (fetch = FetchType.LAZY)for these fields did not work, because the entities separated after extraction, and zeros will appear in my WebApp.
Okay, so the next thing I did was to prevent the shutdown by putting my retrieval operations in a StatefulSessionBean with an extended PersistenceContext.
@PersistenceContext(unitName="unitname", type=PersistenceContextType.EXTENDED)
private EntityManager em;
This works, but also causes strange side effects (primarily ConcurrentAccessExceptionson some page reloads, which I could fix by setting some openjpa property) Servlets need their own echbs-ejbs, since they do not integrate with SFSB. Atm most things seem to work fine, but I expect s ** t to hit the fan soon.
My question is that I'm wrong. It all seems a little uncomfortable to me. Using a stateful bean when there is no real conversation, and the user can leave at any time without running some @ Remove-Method. It is necessary to close resources in a timeout when the user has left for a long time, as a result of which there are many open unused SFSBs.
LazyLoading as a whole is a pretty simple thing, but in Java EE, I don’t understand how to do this. What is the best practice?
Thank.
UPDATE
@SuppressWarnings("unchecked")
public <T extends BasicEntity> T loadLazyField(T entity, String field) throws NoSuchFieldException {
if (!typeHasField(entity.getClass(), field)) {
throw new NoSuchFieldException(entity.getClass().getSimpleName() + " has no field called " + field);
}
String queryString = String.format("SELECT x FROM %s x WHERE x = :entity LEFT JOIN FETCH x.%s", entity.getClass()
.getSimpleName(), entity, field);
Query q = em.createQuery(queryString);
q.setParameter("entity", entity);
return (T) q.getSingleResult();
}
@SuppressWarnings("unchecked")
public <T extends BasicEntity> T loadLazyFields(T entity, String[] fields) throws NoSuchFieldException {
String queryString = String.format("SELECT x FROM %s x WHERE x = :entity", entity.getClass().getSimpleName());
for (String field : fields) {
if (!typeHasField(entity.getClass(), field)) {
throw new NoSuchFieldException(entity.getClass().getSimpleName() + " has no field called " + field);
}
queryString += String.format(" LEFT JOIN FETCH x.%s", field);
}
Query q = em.createQuery(queryString);
q.setParameter("entity", entity);
return (T) q.getSingleResult();
}
private boolean typeHasField(Class<?> type, String field) {
try {
type.getDeclaredField(field);
return true;
} catch (NoSuchFieldException e) {
return false;
}
}