使用QueryDSL

在尝试弄清QueryDSL如何使用Java 8 Optional属性时遇到了一些麻烦。

我已经配置了QueryDSL,并且tests?field=value之类的查询正在处理String属性。但是,由于类的某些getter具有可选的返回类型,因此生成的QTest类包含SimplePath<Optional<String>>,而不是String属性的简单StringPath。见下文:

Test.class

@QueryEntity
@Document(collection = "test")
public class Test {

  private String field;

  private String optionalField;

  Test(String field,String optionalField) {
    this.field = field;
    this.optionalField = optionalField;
  }

  public String getField() {
    return field;
  }

  public Optional<String> getOptionalField() {
    return Optional.ofNullable(optionalField);
  }
}

生成的QTest.class

@Generated("com.querydsl.codegen.EntitySerializer")
public class QTest extends EntityPathBase<Test> {

    private static final long serialVersionUID = -609090735L;

    public static final QTest test = new QTest("test");

    public final StringPath field = createString("field");

    public final ComparablePath<java.util.UUID> id = createComparable("id",java.util.UUID.class);

    public final SimplePath<java.util.Optional<String>> optionalField = createSimple("optionalField",java.util.Optional.class);
}

数据库中的对象是这样的:

{
    "field":"value","optionalField":"optionalValue"
}

控制器:

@RestController
@RequestMapping("/tests")
public class TestController {

  private final TestService testService;

  @Inject
  public TestController (final TestService testService) {
    this.testService = testService;
  }

  @GetMapping()
  public ResponseEntity<Page<Test>> getallWithPredicate(Pageable pageable,@QuerydslPredicate(root = Test.class) Predicate predicate) {
    return new ResponseEntity<>(this.testService.getallTestsWithPredicate(pageable,predicate),HttpStatus.OK);
  }

  @PostMapping
  public ResponseEntity<Test> createTest(@RequestBody Test test) {
    return new ResponseEntity<>(this.testService.createTest(test),HttpStatus.CREATED);
  }
}

服务:

@Service
public class TestService {

  private final TestRepository testRepository;

  @Inject
  public TestService(final TestRepository repo) {
    this.testRepository = repo;
  }

  public Page<Test> getallTestsWithPredicate(Pageable pageable,Predicate predicate) {
    return this.testRepository.findAll(predicate,pageable);
  }

  public Test createTest(Test test) {
    Test savedTest = testRepository.save(test);
    return savedTest;
  }
}

还有存储库:

@Repository
public interface TestRepository extends JpaRepository<Test,String>,QuerydslPredicateExecutor<Test>,QuerydslBinderCustomizer<QTest> {

  @Override
  default public void customize(QuerydslBindings bindings,QTest root) {
    bindings.bind(String.class).first((StringPath path,String value) -> path.containsIgnoreCase(value));
  }
}

因此,首先,我想在我的两个字段上处理一个containsIgnoreCase。这个containsIgnoreCase在普通字段上可以正常工作。 但是当涉及到Optional时,请求如下:tests?optionalField=optionalValue我收到了此错误消息:

java.lang.ClassCastException: com.querydsl.core.types.dsl.SimplePath cannot be cast to com.querydsl.core.types.dsl.StringPath
    at org.springframework.data.querydsl.binding.QuerydslBindings$MultiValueBindingAdapter.bind(QuerydslBindings.java:506) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.invokeBinding(QuerydslPredicateBuilder.java:139) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
    at org.springframework.data.querydsl.binding.QuerydslPredicateBuilder.getPredicate(QuerydslPredicateBuilder.java:113) ~[spring-data-commons-1.13.10.RELEASE.jar:na]
...

由于此字段生成了QTest类型(SimplePath<Optional<String>>而不是StringPath),因此这似乎是正常现象,但事实是我找不到任何有效的处理方式此optionalField。

所以我的问题是: QueryDSL可以使用Optional<String>值吗?如果是这样,我应该如何查询这些字段?

谢谢您的帮助! :)

llk4j 回答:使用QueryDSL

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3094707.html

大家都在问