Ken*_*nco 7 java spring querydsl spring-data
Spring Boot 1.3.2.RELEASE
QueryDSL 3.7.2
QueryDSL Maven插件1.1.3
Hibernate 4.3.11.Final
目前,我有一个Spring Boot应用程序,它使用Spring Data JPA(由Hibernate支持)具有一些基本的CRUD功能,并使用Spring Data Envers进行审计.我还有以下端点来检索实体列表:
现在,我想使用Spring通过@QuerydslPredicate注释提供的新QueryDSL支持.这适用于大多数字段或子实体,但它似乎不适用于子实体的集合.文档,博客文章等似乎不包括这种情况 - 我能找到的唯一信息是它支持简单集合的"in"(即字符串的集合等).
所以,我的实体设置如下:
Person.java
@Data
@Entity
@Audited
public class Person {
@Id
private long id;
private String name;
private List<Pet> pets = new ArrayList<>();
}
Run Code Online (Sandbox Code Playgroud)
Pet.java
@Data
@Entity
@Audited
public class Pet {
@Id
private long id;
private int age;
}
Run Code Online (Sandbox Code Playgroud)
我使用the生成我的Q类com.mysema.maven:apt-maven-plugin,它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);
Run Code Online (Sandbox Code Playgroud)
如果我尝试查询这个,我得到一个例外:
查询:
例外:
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]
Run Code Online (Sandbox Code Playgroud)
现在这个查询看起来像是在尝试解析propertyPath Person.pets.age.它正确识别Person.pets为a ListPath,然后尝试识别CompanyAddress.addressLine1(这似乎是正确的).问题是,它试图使用实体路径来获取类,而ListPath不是QPet:
Field field = ReflectionUtils.findField(entityPath.getClass(), path.getSegment());
Object value = ReflectionUtils.getField(field, entityPath);
Run Code Online (Sandbox Code Playgroud)
以下查询按预期工作:
我的期望是通过使用?pets.age=5,将构建以下谓词:
QPerson.person.pets.any().age.eq(5)
Run Code Online (Sandbox Code Playgroud)
Spring的QuerydslPredicate支持目前是否可以实现?或者我应该从查询参数手动构建谓词?
作为一个额外的问题,QuerydslPredicate有以下几种可能.假设我在pet上有firstName和lastName,我想用以下命令运行查询name=Bob:
我希望查询谓词像这样构建:
final BooleanBuilder petBuilder = new BooleanBuilder();
petBuilder.and(QPet.firstName.equals("Bob").or(QPet.lastName.equals("Bob")));
Run Code Online (Sandbox Code Playgroud)
那可能吗?从查看自定义方法QuerydslBinderCustomizer看起来不像它,因为你需要绑定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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2994 次 |
| 最近记录: |