Java Spring@querydsl谓词问题 使用的图书馆

Java Spring@querydsl谓词问题 使用的图书馆,java,spring,spring-data,querydsl,Java,Spring,Spring Data,Querydsl,弹簧靴1.3.2.1释放 QueryDSL 3.7.2 QueryDSL Maven插件1.1.3 Hibernate 4.3.11.1最终版本 问题 目前,我有一个SpringBoot应用程序,它使用SpringDataJPA(由Hibernate支持)具有一些基本的CRUD功能,并使用SpringDataEnvers进行审计。我还有以下端点从中检索实体列表: 现在,我想通过@querydsldpredicate注释使用。这适用于大多数字段或子实体,但似乎不适用于子实体的集合。文档、博客帖子

弹簧靴1.3.2.1释放

QueryDSL 3.7.2

QueryDSL Maven插件1.1.3

Hibernate 4.3.11.1最终版本

问题 目前,我有一个SpringBoot应用程序,它使用SpringDataJPA(由Hibernate支持)具有一些基本的CRUD功能,并使用SpringDataEnvers进行审计。我还有以下端点从中检索实体列表:

现在,我想通过
@querydsldpredicate
注释使用。这适用于大多数字段或子实体,但似乎不适用于子实体的集合。文档、博客帖子等似乎没有涵盖这种情况——我能找到的唯一信息是,它支持简单集合(即字符串集合等)的“in”

因此,我的实体设置如下:

Person.java

@Data
@Entity
@Audited
public class Person {

    @Id
    private long id;

    private String name;

    private List<Pet> pets = new ArrayList<>();

}
@Data
@Entity
@Audited
public class Pet {

    @Id
    private long id;

    private int age;

}
我使用
com.mysema.maven:apt-maven插件
生成我的Q类,该插件使用以下字段生成我的
QPerson

public final ListPath<com.test.Pet, com.test.QPet> pets = this.<com.test.Pet, com.test.QPet>createList("pets", com.test.Pet.class, com.test.QPet.class, PathInits.DIRECT2);
现在这个查询看起来像是在试图解析propertyPath
Person.pets.age
。它将
Person.pets
正确识别为
列表路径
,然后尝试识别
公司地址.addressLine1
(这似乎是正确的)。问题是,它试图使用实体路径来获取类,即
ListPath
,而不是
QPet

Field field = ReflectionUtils.findField(entityPath.getClass(), path.getSegment());
Object value = ReflectionUtils.getField(field, entityPath);
以下查询按预期工作:

我的期望是,通过使用
?pets.age=5
,将构建以下谓词:

QPerson.person.pets.any().age.eq(5)
Spring的QuerydslPredicate支持目前可以做到这一点吗?还是应该从查询参数手动构建谓词

补充问题 另外一个问题是,QuerydslPredicate是否可以执行以下操作。假设我在pet上有一个firstName和lastName,我只想用
name=Bob
运行一个查询:

我希望查询谓词的构建方式如下:

final BooleanBuilder petBuilder = new BooleanBuilder();
petBuilder.and(QPet.firstName.equals("Bob").or(QPet.lastName.equals("Bob")));
可能吗?从
QuerydslBinderCustomizer
的customize方法来看,情况似乎并非如此,因为您需要绑定Q类的一个字段。我猜我想做的事情不受支持


如果这些都不可能,那么我将坚持手动创建谓词,并将其传递到存储库。

您可以使用
QuerydslBinderCustomizer
来实现您的目的。以下是一些可以帮助您解决问题的示例代码:

public interface PersonRepository extends JpaRepository<Job, Integer>,
        QueryDslPredicateExecutor<Person>, QuerydslBinderCustomizer<QJob> {

    @Override
    public default void customize(final QuerydslBindings bindings, final QPerson person)     {
        bindings.bind(person.pets.any().name).first((path, value) -> {
            return path.eq(value);
        });
    }
}
public interface PersonRepository扩展了JpaRepository,
QueryDslPredicateExecutor,QuerydslBinderCustomizer{
@凌驾
公共默认void自定义(最终QuerydslBindings绑定,最终QPerson个人){
bindings.bind(person.pets.any().name).first((路径,值)->{
返回路径eq(值);
});
}
}

我遇到了同样的错误。但是我注意到,使用QuerydslAnnotationProcessor插件(而不是JPA注释处理器)可以按预期查询实体的子集合。您只需使用@QueryEntity注释标记所有实体类。(JPA注释处理器自动为@Entity注释类生成查询类。)

在您的pom中:

          <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/annotations</outputDirectory>
                            <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>4.1.3</version>
                    </dependency>
                </dependencies>
            </plugin>

com.mysema.maven
aptmaven插件
1.1.3
生成源
过程
目标/生成的源/注释
com.querydsl.apt.QuerydslAnnotationProcessor
com.querydsl
querydsl公寓
4.1.3

我相信我遇到了您遇到的异常,因为我从JPA注释处理器更改为QuerySlanotationProcessor,由于某种原因我不记得了,并且忽略了用@QueryEntity注释标记所讨论列表的实体类。然而,我也相信我还有另一个SpringDataREST\JPA支持的API,它使用了2017年8月构建的JPA注释处理器,我相信查询实体的子集合会如期工作。今天晚些时候我将能够确认这一点,并提供相关依赖项的版本(如果是这样的话)。也许这个问题已经解决了

我也发现这方面的文档不足。特别是如何利用“in”功能——我确实找到了这个答案,它至少解释了如果你想为给定字段提供多个匹配项,如何“in”工作——谢谢你的帖子。我不再参与那个特定的项目了,所以我无法立即验证它,但我会在接下来的几天里尝试建立一个小项目,看看这是否解决了问题。
          <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/annotations</outputDirectory>
                            <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>4.1.3</version>
                    </dependency>
                </dependencies>
            </plugin>