spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
3.02k stars 1.42k forks source link

error raise execute subquery in case-when #3632

Closed runnz121 closed 1 month ago

runnz121 commented 1 month ago

The query that I wrote in Spring Boot version 3.3.0 (Hibernate 6.5.2) executed perfectly. However, when I updated the version to Spring Boot 3.3.4 (Hibernate 6.5.3 Final), an error was raised stating that:

Cannot invoke "org.hibernate.query.sqm.SqmExpressible.getSqmType()" because the return value of "org.hibernate.query.sqm.tree.select.SqmSelection.getExpressible()" is null

So, I found out the reason why the error was raised and found that the 'selection' method was changed, and this changed method checks a variable that was not initialized:

private SqmExpressible expressibleType;

in SqmSubQuery class

The error was raised in the following part of the SemanticQueryBuilder.class > visitSubquery (method):


6.5.2

if (selections.size() == 1) {
  subQuery.applyInferableType(selections.get(0).getNodeType())
}

6.5.3

if (selections.size() == 1) {
  subQuery.applyInferableType(selections.get(0).getExrpessible().getSqmType())
}

the execute query is

 .when(
          jpaQueryFactory
                  .select(
                          new CaseBuilder()
                                  .when(codeAsInt(productInventory.status).longValue().sum()
                                                .eq(productPricingQuantity.count()))
                                  .then(ProductStatus.SOLD_OUT.getCode())
                                  .otherwise(ProductStatus.SALE.getCode())
                  )
                  .from(productPricingQuantity)
                  .join(productInventory)
                  .on(productInventory.key.eq(productPricingQuantity.productInventory.key)
                              .and(productInventory.deleted.isFalse()))
                  .where(productPricingQuantity.pricing.key.eq(childProductPricing.key))
                  .ne(ProductStatus.SALE.getCode())
  )
  .then(ProductStatus.SOLD_OUT.getCode())
  .otherwise(ProductStatus.SALE.getCode());

please check it

Thank you.

mp911de commented 1 month ago

All mentioned types are either Querydsl types or Hibernate types. Neither of these is managed by Spring Data. Please raise a ticket with one of these libraries.