java 来自使用 join 的 Spring Data JPA 规范的不同结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33025213/
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
Distinct results from Spring Data JPA Specification that uses join
提问by Andrew Mairose
I have the following Specification
that I use to query for any Contact
entities that are tied to certain ManagedApplication
entities. I pass in a Collection<Long>
that contains the ids of the ManagedApplication
entities that I am searching for.
我有以下Specification
用于查询Contact
与某些ManagedApplication
实体相关联的任何实体的以下内容。我传入一个Collection<Long>
包含ManagedApplication
我正在搜索的实体的 ID 。
public static Specification<Contact> findByApp(final Collection<Long> appIds) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
}
}
}
I pass this specification to the .findAll()
method of my PagingAndSoringRepository
to retrieve a Page<Contact>
that will contain all Contact
entities that meet the search criteria.
我将此规范传递给.findAll()
my的方法PagingAndSoringRepository
以检索Page<Contact>
将包含Contact
满足搜索条件的所有实体的 。
Here is the Repository
.
这是Repository
.
@Repository
public interface PagingAndSortingContactRepository extends PagingAndSortingRepository<Contact, Long>, JpaSpecificationExecutor<Contact> {
}
And here is how I'm calling the .findAll()
method.
这是我调用该.findAll()
方法的方式。
final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
This works and returns all Contact
entities that are tied to any of the ManagedApplication
entities that correspond to the ids passed in. However, since I am calling .join()
to join the Contact
entity with the ManagedApplication
entity, if one Contact
has multiple ManagedApplication
entities in the list of app ids, then the query will return duplicate Contact
entities.
这有效并返回与传入的 id 对应的Contact
任何实体相关联的所有实体ManagedApplication
。 但是,由于我正在调用.join()
将Contact
实体与ManagedApplication
实体连接,如果应用程序 id 列表中Contact
有多个ManagedApplication
实体,则查询将返回重复的Contact
实体。
So what I need to know is, how can I get only distinct Contact
entities returned from my query using this Specification
?
所以我需要知道的是,如何Contact
使用 this 从我的查询中只返回不同的实体Specification
?
I know that CriteriaQuery
has a .distinct()
method that you can pass a boolean value to, but I am not using the CriteriaQuery
instance in the toPredicate()
method of my Specification
.
我知道CriteriaQuery
有一个.distinct()
方法可以将布尔值传递给它,但我没有CriteriaQuery
在toPredicate()
我的Specification
.
Here are the relevant sections of my metamodels.
这是我的元模型的相关部分。
Contact_.java:
联系人_.java:
@StaticMetamodel(Contact.class)
public class Contact_ {
public static volatile SingularAttribute<Contact, String> firstNm;
public static volatile SingularAttribute<Contact, String> lastNm;
public static volatile SingularAttribute<Contact, String> emailAddress;
public static volatile SetAttribute<Contact, ManagedApplication> managedApplications;
public static volatile SetAttribute<Contact, ContactToStructure> contactToStructures;
}
ManagedApplication_.java
ManagedApplication_.java
@StaticMetamodel(ManagedApplication.class)
public class ManagedApplication_ {
public static volatile SingularAttribute<ManagedApplication, Integer> managedApplicationId;
}
回答by Ish
Use the query
parameter in your toPredicate
method to invoke the distinct method.
使用方法中的query
参数toPredicate
来调用不同的方法。
Sample below:
示例如下:
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
query.distinct(true);
...