Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 使用Spring DATA-JPA的集合的带IN运算符的JPA条件查询_Java_Spring_Jpa_Spring Data Jpa_Criteriaquery - Fatal编程技术网

Java 使用Spring DATA-JPA的集合的带IN运算符的JPA条件查询

Java 使用Spring DATA-JPA的集合的带IN运算符的JPA条件查询,java,spring,jpa,spring-data-jpa,criteriaquery,Java,Spring,Jpa,Spring Data Jpa,Criteriaquery,在我的应用程序中,两个实体之间有以下映射: @Entity public class Applicant { private Integer id; .... private Set<Document> documents; ... Getters and Setters ... @OneToMany(fetch = FetchType.LAZY, mappedBy = "applicant", cascade = Cascade

在我的应用程序中,两个实体之间有以下映射:

@Entity
public class Applicant {
     private Integer id;
     ....
     private Set<Document> documents;

     ... Getters and Setters ...

     @OneToMany(fetch = FetchType.LAZY, mappedBy = "applicant", cascade = CascadeType.ALL)
     public Set<Document> getDocuments() {
     return documents;
     }

    public Applicant setDocuments(Set<Document> documents) {
        this.documents = documents;
        return this;
    }
}
我想使用Spring数据规范org.springframework.Data.jpa.domain,使用findAllSpec规范方法筛选我的应用程序位置中的一些申请人

但是,我的问题是,我想创建一个规范,其中包含一组参数,并构建一个规范来筛选未链接到本文档中一个(而非全部)参数的申请人

我尝试过不同的方法,但没有一种有效。。。我不知道我是否忘记了什么。 第一个是使用criteriaBuilder和value方法

public static Specification<Applicant> applicantHasDoc(final Set<Document> documents) {
        return new Specification<Applicant>() {
            @Override
            public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                /*
                    Problem during parsing the query :
                    select *
                    from
                        applicant applicant0_ cross join document documents1_
                    where
                        applicant0_.id=documents1_.applicant
                        and (. in (? , ?))
                */
                Expression<Set<Document>> documentExpression = root.get(Applicant_.documents);
                return cb.in(documentExpression).value(documents);
        };
    }
这将返回一个GrammarSQL异常。。。您可以在代码中的申请者字段上看到简化的SQL查询

第二种解决方案是使用元模型,直接在申请者的根目录中:

public static Specification<Applicant> applicantHasDoc(final Set<Document> documents) {
        return new Specification<Applicant>() {
            @Override
            public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                /*        
                    Error with this type of criteria : Parameter value [com.myapp.entity.Document@1b275eae] did not match expected type [java.util.Set (n/a)]
                */
                    return root.get(Applicant_.documents).in(documents);
            }
        };
    }
我在代码中添加了每个解决方案的结果。。。它们都不起作用

本规范的主要目的是与其他类似规范一起使用:

List<Applicant> applicants = findAll(where(applicantHasDoc(documents).and(otherSpec(tags)).and(anotherSpec(mobilities), page);
所以我只能在Spring数据JPA规范中工作

其他信息:我正在使用H2数据库


谢谢你的帮助。

我找到了正确的方法,但我所有的尝试都失败了,因为我的思维方式像object,而不是SQL。。。但CriteriaQuery是构建SQL查询的对象包装器

因此,我用SQL编写了我想要的查询,并找到了解决方案:

我在SQL中想要的是:

select * 
from applicant applicant0_ inner join document documents1_ on applicant0_.id=documents1_.applicant where documents1_.id in (? , ?)
因此,我的谓词似乎如下所示:

   public static Specification<Applicant> applicantHasDoc(final Set<Document> documents) {
        return new Specification<Applicant>() {
            @Override
            public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                SetJoin<Applicant, Document> documentApplicantJoin = root.join(Applicant_.documents);
                return documentApplicantJoin.in(documents);


            }
        };
    }

我找到了正确的方法,我所有的尝试都是失败的,因为我的思维方式像对象,而不是SQL。。。但CriteriaQuery是构建SQL查询的对象包装器

因此,我用SQL编写了我想要的查询,并找到了解决方案:

我在SQL中想要的是:

select * 
from applicant applicant0_ inner join document documents1_ on applicant0_.id=documents1_.applicant where documents1_.id in (? , ?)
因此,我的谓词似乎如下所示:

   public static Specification<Applicant> applicantHasDoc(final Set<Document> documents) {
        return new Specification<Applicant>() {
            @Override
            public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                SetJoin<Applicant, Document> documentApplicantJoin = root.join(Applicant_.documents);
                return documentApplicantJoin.in(documents);


            }
        };
    }
此外,在执行此类联接时,可能需要设置distinct select query.distincttrue。此外,在执行此类联接时,可能需要设置distinct select query.distincttrue。