Background
I recently started a new Java EE 6 object, using JBoss and Hibernate. From earlier projects, I have experience with Glassfish using Eclipselink as JPA provider.
In my earlier project, I mapped up all relations as Lists, and when I knew I was going to need large batches of data from a relationship, I would fetch the data needed. If I forgot to fetch something, it could be lazy loaded later from the view/controller layer. Using Hibernate, I discovered that things works very differently than other providers regarding lazy loading and fetches (not allowing lazy loading outside an EJB, not allowing more than a single fetch/eager load).
Question
What is the de-facto standard of handling fetching with Hibernate? I see a few possibilities:
Map one-to-many to List as earlier, but using @IndexColumn. Use fetch through criteria api, causing joins.
Pros: design looks decent.
Cons: need to change table structure, joins have very bad performance with a deep structure.Map one-to-many to Set. Allows multiple fetches.
Pros: no need for @IndexColumn.
Cons: No sorting, would often need to convert it to a List and back to use many JSF 2 components that wants a list.Map one-to-many to List and use hibernate specific @Fetch annotation on entity classes, mostly with FetchMode.SUBSELECT, together with lazy loading. EJB methods would not use fetches, but simply make a simple select, then manually read from the selected object and "lazy load" relations that we want to fetch.
Pros: very good performance due to subselects. No need for @IndexColumn.
Cons: very weird-looking looking EJB methods, due to the need to manually load relationsships (see below for example).
Example of #3
public List<User> findAllUsers(){
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> from = cq.from(User.class);
List<User> users = em.createQuery(cq).getResultList();
if(users.isEmpty())
return users;
users.get(0).getRoleList().size();
users.get(0).getUserHasCompanyList().size();
users.get(0).getUserInUnitList().size();
return users;
}
With such a common scenario as wanting a few entities loaded with relationships to use in the controller/view layer, is there really no better alternative?