gpt4 book ai didi

java - Spring @QuerydslPredicate 问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:31:57 25 4
gpt4 key购买 nike

使用的库

Spring Boot 1.3.2.RELEASE

查询DSL 3.7.2

QueryDSL Maven 插件 1.1.3

hibernate 4.3.11.Final

问题

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

http://localhost:8080/test-app/list

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

所以,我的实体是这样设置的:

Person.java

@Data
@Entity
@Audited
public class Person {

@Id
private long id;

private String name;

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

}

Pet.java

@Data
@Entity
@Audited
public class Pet {

@Id
private long id;

private int age;

}

我使用 com.mysema.maven:apt-maven-plugin 生成我的 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);

如果我尝试对此进行查询,则会出现异常:

查询:

http://localhost:8080/test-app/list?pets.age=5

异常:

10:21:37,523 ERROR [org.springframework.boot.context.web.ErrorPageFilter] (http-/127.0.0.1:8080-1) Forwarding to error page from request [/list] due to exception [null]: java.lang.NullPointerException
at org.springframework.util.ReflectionUtils.getField(ReflectionUtils.java:143) [spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.reifyPath(QuerydslPredicateBuilder.java:185) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.reifyPath(QuerydslPredicateBuilder.java:188) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.getPath(QuerydslPredicateBuilder.java:167) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.invokeBinding(QuerydslPredicateBuilder.java:136) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.getPredicate(QuerydslPredicateBuilder.java:111) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver.resolveArgument(QuerydslPredicateArgumentResolver.java:106) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver.resolveArgument(QuerydslPredicateArgumentResolver.java:48) [spring-data-commons-1.11.2.RELEASE.jar:]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]

现在这个查询看起来像是在尝试解析 propertyPath Person.pets.age。它正确地将 Person.pets 识别为 ListPath,然后尝试识别 CompanyAddress.addressLine1(这似乎是正确的)。问题是,它试图使用实体路径来获取类,即 ListPath 而不是 QPet:

Field field = ReflectionUtils.findField(entityPath.getClass(), path.getSegment());
Object value = ReflectionUtils.getField(field, entityPath);

以下查询按预期工作:

http://localhost:8080/test-app/list?name=Bob

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

QPerson.person.pets.any().age.eq(5)

Spring 的 QuerydslPredicate 支持目前可以实现吗?还是我应该根据查询参数手动构建谓词?

附加问题

作为附加问题,以下是否可以使用 QuerydslPredicate。假设我在宠物上有名字和姓氏,我想只使用 name=Bob 运行查询:

http://localhost:8080/test-app/pet/list?name=Bob

我想要这样构建查询谓词:

final BooleanBuilder petBuilder = new BooleanBuilder();
petBuilder.and(QPet.firstName.equals("Bob").or(QPet.lastName.equals("Bob")));

这可能吗?从 QuerydslBinderCustomizer 的自定义方法来看,它似乎不是,因为您需要绑定(bind) 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);
});
}
}

关于java - Spring @QuerydslPredicate 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35918824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com