13

我有一个标准可以返回应用程序所需的所有数据,基本上:

Criteria criteria = session.createCriteria(Client.class);
criteria.createAlias("address", "address");
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();

问题是关系客户端/地址是双向的:客户端有一个地址,一个地址可能属于多个客户端。

我想根据它们的 pk 检索“单个”客户端对象,当然,一些客户端显示在表格中。

因为首先执行 setFirstResult/setMaxResults,所以我在已应用的限制内获得了重复的客户端。之后(未使用分组依据的应用程序级别)休眠消除了重复的客户端,因此我最终得到的客户端少于 setMaxResults 中指定的最大值。

无法分组(投影组),因为它不会返回客户端/地址中所需的所有列,只返回查询分组依据的组。

(总而言之,我的表每页有 100 个结果,但在丢弃重复项后,我有 98 个结果而不是 100 个......)这是因为限制:LIMIT 0,100 应用在休眠组之前,应该在之后执行)

4

3 回答 3

10

正如“Ashish Thukral”链接的线程中指出的那样,下一行解决了这个问题:

criteria.setFetchMode("address.clients", FetchMode.SELECT);

它可以防止导致问题发生的连接。

当然,可以从 xml 配置文件中删除 fetch="join" ,但此解决方案不会影响可能正在检索 bean 的其他位置。

于 2013-09-18T15:14:50.527 回答
7

如果您根据 id 查找 Client,如下所示。根据您的标准,不需要最大和初始大小,因为它总是返回一个客户端。

Criteria criteria = getSession().createCriteria(Client.class);
criteria .add(Restrictions.eq("id", yourClientId);
criteria.createAlias("address", "address");
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();

如果您根据 id 查找地址,如下所示。

Criteria criteria = getSession().createCriteria(Client.class);
criteria.createAlias("address", "address");
criteria .add(Restrictions.eq("address.id", yourAddressId);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();
于 2013-08-16T15:18:00.383 回答
1

如果我正确理解您的关系,您将在地址中拥有一个客户列表,在每个客户实体类中都有一个地址。所以如果你只是想要一个客户列表,有什么大不了的,你不能让他们通过吗?

Criteria criteria = session.createCriteria(Client.class);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();

为什么要创建别名并使用 distinct_root_entity ?如果您需要获取该地址,当您在 DAO 或 ServiceImpl 中访问它时,Hibernate 无论如何都会为您懒惰地获取它。

如果我错了,请纠正我。

于 2013-08-17T03:32:18.113 回答