2011-06-20 46 views
1

背景的最好方法休眠,获取一个一对多

最近,我开始一个新的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; 
    } 

利用这样的常见情形作为想要加载有关系,控制器/视图层使用几个实体实施例,是真的没有更好的替代?

回答

1

我会建议使用该集的原因如下:

1)不要接触模式。 2)你可以在从数据库中取出数据集后对数据集进行排序。例如:

List<MyType> list = query.list(); 
Collections.sort(list, myComparator); 

3)集可以是既懒惰地,并与任何类型的映射(XML或注释)

预先抓取