Java Hibernate Criteria:不同的实体,然后限制

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18276230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:57:54  来源:igfitidea点击:

Hibernate Criteria: distinct entities and then limit

javahibernategroup-bycriteria

提问by kandan

I have a criteria that returns all data the application requires, basically:

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

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

The problem is that the relation client / address is bidirectional: on client has one address and one address may belong to more than one client.

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

I want to retrieve "single" client objects based on their pk of course, some number of clients as they are displayed in a table.

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

Because the setFirstResult/setMaxResults are executed first I am getting duplicated clients within the already applied limits. After (application level as not group by was used) hibernate gets rids of the duplicate clients so I end up with less clients that the maximum specified in the setMaxResults.

因为首先执行 setFirstResult/setMaxResults,所以我在已应用的限制内获得了重复的客户端。在(使用应用程序级别不是 group by)之后,hibernate 摆脱了重复的客户端,所以我最终得到的客户端少于 setMaxResults 中指定的最大值。

Cannot group by (projection group) as it won't return all columns required in client/addresses, only the group the query is grouping by.

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

(To sum up, My table has 100 results per page but after discarding duplicates I have 98 results instead of 100...) that is because the limit : LIMIT 0,100 is applied BEFORE hibernate groups when it should be performed AFTER)

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

采纳答案by kandan

As it is pointed out in the thread linked by "Ashish Thukral" next line solves this:

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

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

It prevents the join that causes the problem to be made.

它可以防止导致出现问题的连接。

Of course, it is possible to remove fetch="join" from the xml configuration file but this solution does not affect other places where the beans may be being retrieved.

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

回答by Prabhakaran Ramaswamy

If you looking for Client based on the id as follows. Based on the your criteria there is no need for max and init size because it always return one client.

如果您根据 id 查找 Client,如下所示。根据您的标准,不需要 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();

If you looking for Address based on the id as follows.

如果您根据 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();

回答by Ashish Thukral

If I understand your relations correctly, you will have a list of client in Address and One address in each Client Entity class. So if you just want a list of client, what's the big deal, can't you just get them by

如果我正确理解您的关系,您将在每个客户端实体类中的 Address 和 One address 中有一个客户端列表。所以如果你只是想要一份客户名单,有什么大不了的,你就不能通过

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

Why are you creating an alias and using distinct_root_entity ? If you need to get that address, when you access it in your DAO or ServiceImpl, Hibernate will anyways fetch it lazily for you.

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

Correct me if I am wrong.

如果我错了,请纠正我。