Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 与使用join的Spring数据JPA规范不同的结果_Java_Hibernate_Jpa_Spring Data Jpa_Criteria Api - Fatal编程技术网

Java 与使用join的Spring数据JPA规范不同的结果

Java 与使用join的Spring数据JPA规范不同的结果,java,hibernate,jpa,spring-data-jpa,criteria-api,Java,Hibernate,Jpa,Spring Data Jpa,Criteria Api,我有以下规范,用于查询与某些ManagedApplication实体关联的任何联系人实体。我传入一个集合,该集合包含我正在搜索的ManagedApplication实体的ID public static Specification<Contact> findByApp(final Collection<Long> appIds) { return new Specification<Contact>() { @Override

我有以下
规范
,用于查询与某些
ManagedApplication
实体关联的任何
联系人
实体。我传入一个
集合
,该集合包含我正在搜索的
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);
        }
    }
}
下面是我如何调用
.findAll()
方法的

final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
ManagedApplication.java

@StaticMetamodel(ManagedApplication.class)
public class ManagedApplication_ {
    public static volatile SingularAttribute<ManagedApplication, Integer> managedApplicationId;
}
@StaticMetamodel(ManagedApplication.class)
公共类管理应用程序{
公共静态属性ManagedApplication ID;
}

使用
toPredicate
方法中的
query
参数调用distinct方法

样本如下:

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);
    ...
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder cb){
最终谓词appPredicate=root.join(联系.managedApplications)
.get(ManagedApplication_u.managedApplicationId).in(appid);
query.distinct(true);
...

可以添加一个新的静态方法

public static Specification<Object> distinct() {
    return (root, query, cb) -> {
        query.distinct(true);
        return null;
    };
}

感谢您提供此解决方案,它非常有效!此外,为了澄清问题,您必须添加
query.distinct(true)
添加到每个需要此独特语句的谓词。仅将此语句添加到任何谓词并使其在整个查询中工作是不够的。这是如何工作的?我的意思是,如果您使用纯MySQL语法连接一些形成多对多关系的表,以便您可以选择左表中具有证书的行在右表的列中的值中,尽管使用了SELECT DISTINCT子句,但如果左表中的一行与右表中的多行相关,仍然会得到重复的结果。
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);
    ...
public static Specification<Object> distinct() {
    return (root, query, cb) -> {
        query.distinct(true);
        return null;
    };
}
Specification.where(
    YourStaticClassWhereYouCreatedTheUpperMethod.distinct().and(..))