背景的最好方法休眠,获取一个一对多
最近,我开始一个新的Java EE 6的对象,使用JBoss和Hibernate。从早期的项目中,我有使用Eclipselink作为JPA提供者的Glassfish经验。
在我之前的项目中,我将所有关系映射为列表,并且当我知道我将需要关系中的大批量数据时,我将获取所需的数据。如果我忘记取回某些内容,则可能会稍后从视图/控制器层中加载该内容。使用Hibernate,我发现事情与其他提供者有关延迟加载和提取(不允许在EJB外延迟加载,不允许多个提取/加载负载)的工作方式完全不同。
问题
什么是处理与Hibernate获取事实上的标准呢?我看到了一些可能性:
将一对多映射到List,但使用@IndexColumn。使用通过标准API进行读取,导致连接。
优点:设计看起来不错。
缺点:需要改变表格结构,加入具有非常糟糕的性能和深层次的结构。将一对多映射到Set。允许多次提取。
优点:不需要@IndexColumn。
缺点:没有排序,通常需要将其转换为列表并返回使用许多想要列表的JSF 2组件。将一对多映射到List,并在实体类上使用hibernate特定的@Fetch注释,大多数情况下使用FetchMode.SUBSELECT和延迟加载。 EJB方法不会使用提取,而只是简单地进行选择,然后从选定的对象中手动读取,并且我们要获取“延迟加载”关系。
优点:由于子选择而表现非常好。不需要@IndexColumn。
缺点:由于需要手动加载关系(请参阅下面的示例),因此看起来很怪异的EJB方法。
的#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;
}
利用这样的常见情形作为想要加载有关系,控制器/视图层使用几个实体实施例,是真的没有更好的替代?