{"record":{"id":"03715a4d26a09aea","repo":"hibernate/hibernate-orm","slug":"could-not-determine-valuemapping-for-sqmparameter","errorCode":null,"errorMessage":"Could not determine ValueMapping for SqmParameter: {}","messagePattern":"Could not determine ValueMapping for SqmParameter: (.+?)","errorType":"exception","errorClass":"ConversionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java","lineNumber":6671,"sourceCode":"\t\t\t\tif ( basicTypeForJavaType != null ) {\n\t\t\t\t\treturn basicTypeForJavaType;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif ( paramSqmType instanceof EntityDomainType<?> entityDomainType ) {\n\t\t\t\t\t\treturn resolveEntityPersister( entityDomainType );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( paramSqmType instanceof SingularAttribute<?, ?> singularAttribute ) {\n\t\t\t\t\t\tif ( singularAttribute.getType() instanceof EntityDomainType<?> entityDomainType ) {\n\t\t\t\t\t\t\treturn resolveEntityPersister( entityDomainType );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// inferredMapping is null or JavaObjectType and we cannot deduct the type\n\t\t\t\t\treturn inferredMapping;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tthrow new ConversionException( \"Could not determine ValueMapping for SqmParameter: \" + sqmParameter );\n\t\t}\n\t}\n\n\tprivate static boolean canUseInferredType(MappingModelExpressible<?> bindType, MappingModelExpressible<?> inferredType) {\n\t\tif ( inferredType.getJdbcTypeCount() != 1 ) {\n\t\t\t// The inferred type is an embeddable or entity with embeddable id, which is more concrete\n\t\t\treturn true;\n\t\t}\n\t\tfinal var bindJdbcType = bindType.getSingleJdbcMapping().getJdbcType();\n\t\tfinal var inferredJdbcType = inferredType.getSingleJdbcMapping().getJdbcType();\n\t\t// If the bind type has a different JDBC type, we prefer that over the inferred type.\n\t\treturn bindJdbcType == inferredJdbcType\n\t\t\t|| bindJdbcType instanceof ArrayJdbcType bindArrayType\n\t\t\t\t&& inferredJdbcType instanceof ArrayJdbcType inferredArrayType\n\t\t\t\t&& bindArrayType.getElementJdbcType() == inferredArrayType.getElementJdbcType();\n\t}\n\n\tprivate MappingModelExpressible<?> resolveInferredValueMappingForParameter(MappingModelExpressible<?> inferredValueMapping) {","sourceCodeStart":6653,"sourceCodeEnd":6689,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java#L6653-L6689","documentation":"The parameter-side counterpart of the expression error: resolveInferredValueMappingForParameter matched none of the known shapes (model part, basic mapping, entity persister via singular attribute, ...) and context inference returned nothing usable, so translation fails with a ConversionException naming the SqmParameter.","triggerScenarios":"JPA criteria parameters created as raw ParameterExpression without a usable type (Object.class); parameters in select lists or predicates with no mapped expression on the other side; null-valued bound parameters whose type cannot be inferred; HQL literal-less predicates where both sides are parameters.","commonSituations":"Dynamic query builders that genericize parameter types; queries generated from user filters where a branch compares parameter to parameter; Hibernate version upgrades where previous lenient inference was removed; criteria fragments shared across queries.","solutions":["Create criteria parameters with a concrete type: cb.parameter(String.class) instead of Object.class","Ensure at least one side of each predicate is a mapped path so the parameter can be inferred","Bind with an explicit type hint where the API allows it (setParameter(name, value, type))","Upgrade to the latest 6.x/7.x patch - parameter inference improves release to release"],"exampleFix":"// before\nParameterExpression<Object> p = cb.parameter(Object.class);\ncb.equal(root.get(\"name\"), p);\n\n// after\nParameterExpression<String> p = cb.parameter(String.class);\ncb.equal(root.get(\"name\"), p);","handlingStrategy":"validation","validationCode":"// Validate criteria parameters carry concrete types before compiling\nfor (jakarta.persistence.Parameter<?> p : query.getParameters()) {\n    if (p.getParameterType() == null || p.getParameterType() == Object.class) {\n        throw new IllegalStateException(\"Untyped parameter \" + p + \" - create with cb.parameter(ConcreteType.class)\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(cq).getResultList();\n} catch (RuntimeException e) {\n    if (e.getClass().getSimpleName().equals(\"ConversionException\")\n            && e.getMessage() != null && e.getMessage().contains(\"SqmParameter\")) {\n        log.error(\"Parameter without resolvable mapping - type your cb.parameter(...) calls\");\n    }\n    throw e;\n}","preventionTips":["Always create parameters with a concrete type class","Ensure predicates compare against a mapped path so parameters can be inferred","Add a CI check that fails on ParameterExpression<Object.class>"],"tags":["hibernate","criteria","query-parameter","type-inference"],"backgroundTag":"untyped-query-parameter","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}