Case Statement 和 NVL with Criteria API - IllegalArgumentException: 属性 [SingularAttributeImpmappings.DirectToFieldMapping

Case Statement and NVL with Criteria API - IllegalArgumentException: The attribute [SingularAttributeImpmappings.DirectToFieldMapping

我能够使用 JPA Criteria Builder 建立标准

Java 代码片段

cq.multiselect(root.get(ProductCatalogue_.userId),root.get(ProductCatalogue_.productList));

    Join<ProductCatalogue, ProductList> joinList = root.join(ProductCatalogue_.productList, JoinType.LEFT);
    Join<ProductCatalogue, ProductEmp> joinEmp = root.join(ProductCatalogue_.productEmp, JoinType.LEFT);

我在这里面临的问题不确定如何将 case 语句与我在 SQL

中使用的上述代码和 nvl 一起使用

更新 1

criteriaQuery.multiselect(root.get(ProductCatalogue_.userId),
root.get(ProductCatalogue_.productList),criteriaBuilder.selectCase().
when(criteriaBuilder.equal(root.get(ProductCatalogue_.prodId),"ZCX"),
rootPr.get(ProductList_.prodDesc + " # " + 
rootEmp.get(ProductEmp_.empNo))).otherwise(rootPr.get(ProductList_.prodDesc));

异常

java.lang.IllegalArgumentException: The attribute [SingularAttributeImpl[org.eclipse.persistence.mappings.DirectToFieldMapping[prodDesc-->PRODUCT_LISTS.prodDesc]]] from the managed type [EntityTypeImpl@3567635:ProductList [ javaType: class test.entity.ProductList descriptor: RelationalDescriptor(test.entity.ProductList --> [DatabaseTable(PRODUCT_LISTS)]), mappings: 5]] is not present.

更新 2

Expression<String> stringConcat = 
criteriaBuilder.concat(criteriaBuilder.concat(rootPr.get(ProductList_.prodDesc), " # "), 
rootEmp.get(ProductEmp_.empNo));

错误

missing right parenthesis

因为 SQL 的一部分有一个问号,因为它需要一个参数

THEN (t0.prodDesc = ?) 

我看到这里有两个问题。首先,Path#get(String) needs an attribute name, therefore you can't pass the string concatenation. Second, if you want to select the result of a string concatenation, you have to use CriteriaBuilder#concat() 而不是使用 + 运算符连接的纯 java 字符串。

所以我会试试这个:

Expression<String> stringConcat = criteriaBuilder.concat(
    criteriaBuilder.concat(rootPr.get(ProductList_.prodDesc), " # "), 
    rootEmp.get(ProductEmp_.empNo));

criteriaQuery.multiselect(root.get(ProductCatalogue_.userId), 
    root.get(ProductCatalogue_.productList), 
    criteriaBuilder.selectCase()
        .when(criteriaBuilder.equal(root.get(ProductCatalogue_.prodId),"ZCX"), stringConcat)
        .otherwise(rootPr.get(ProductList_.prodDesc)));

最后,NVL 部分应该在 CriteriaBuilder#isNull() 结果上使用另一个 selectCase() 语句构建:

Expression<Long> userId = criteriaBuilder.selectCase()
    .when(criteriaBuilder.isNull(rootEmp.get(ProductEmp_.userId)), root.get(ProductCatalogue_.userId))
    .otherwise(rootEmp.get(ProductEmp_.userId));