休眠条件:不同的实体,然后限制

2022-09-04 20:10:45

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

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 在休眠组之前应用,而应该在休眠组之后执行)


答案 1

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

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

它可以防止导致问题的联接。

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


答案 2

如果您根据id查找客户端,如下所示。根据您的条件,不需要 max 和 init 大小,因为它始终返回一个客户端。

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();