【发布时间】:2011-06-20 12:01:10
【问题描述】:
背景
我最近使用 JBoss 和 Hibernate 启动了一个新的 Java EE 6 对象。在早期的项目中,我有使用 Eclipselink 作为 JPA 提供程序的 Glassfish 的经验。
在我早期的项目中,我将所有关系映射为列表,当我知道我需要从关系中获取大量数据时,我会获取所需的数据。如果我忘了取东西,它可能会在稍后从视图/控制器层延迟加载。使用 Hibernate,我发现在延迟加载和提取方面,事情的工作方式与其他提供程序非常不同(不允许在 EJB 之外进行延迟加载,不允许多次提取/急切加载)。
问题
使用 Hibernate 处理获取的事实标准是什么?我看到了一些可能性:
像之前一样将一对多映射到 List,但使用 @IndexColumn。使用 fetch through criteria api,导致连接。
优点:设计看起来不错。
缺点:需要更改表结构,连接性能很差深层结构。将一对多映射到 Set。允许多次提取。
优点:不需要@IndexColumn。
缺点:不需要排序,通常需要将其转换为 List 并重新使用许多需要列表的 JSF 2 组件。将一对多映射到 List 并在实体类上使用特定于休眠的 @Fetch 注释,主要使用 FetchMode.SUBSELECT,以及延迟加载。 EJB 方法不会使用 fetches,而只是简单地进行选择,然后手动读取选定对象和我们想要获取的“延迟加载”关系。
优点:非常好的性能,因为子选择。不需要@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;
}
对于这样一个常见的场景,比如希望在控制器/视图层中使用一些加载了关系的实体,真的没有更好的选择吗?
【问题讨论】:
标签: hibernate jpa-2.0 java-ee-6