{"record":{"id":"95eb2f60b465c9f9","repo":"hibernate/hibernate-orm","slug":"can-t-render-value-because-java-type-is-null","errorCode":null,"errorMessage":"Can't render value because java type is null","messagePattern":"Can't render value because java type is null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmLiteral.java","lineNumber":94,"sourceCode":"\t}\n\n\t@Override\n\tpublic String asLoggableText() {\n\t\treturn \"Literal( \" + getLiteralValue() + \")\";\n\t}\n\n\t@Override\n\tpublic void appendHqlString(StringBuilder hql, SqmRenderContext context) {\n\t\tappendHqlString( hql, getJavaTypeDescriptor(), getLiteralValue() );\n\t}\n\n\tpublic static <T> void appendHqlString(StringBuilder sb, @Nullable JavaType<T> javaType, @Nullable T value) {\n\t\tif ( value == null ) {\n\t\t\tsb.append( \"null\" );\n\t\t}\n\t\telse {\n\t\t\tif ( javaType == null ) {\n\t\t\t\tthrow new IllegalArgumentException( \"Can't render value because java type is null\" );\n\t\t\t}\n\t\t\tif ( value instanceof Number || value instanceof Boolean ) {\n\t\t\t\t// We know these are safe to render\n\t\t\t\tsb.append( value );\n\t\t\t}\n\t\t\telse if ( value instanceof Enum<?> enumValue ) {\n\t\t\t\tsb.append( enumValue.getDeclaringClass().getTypeName() ).append( \".\" ).append( enumValue.name() );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Even if this is not 100% correct, our goal with this implementation is to provide\n\t\t\t\t// a cache key or insight into the query structure, not necessarily produce an executable query\n\t\t\t\tappendSingleQuoteEscapedString( sb, javaType.toString( value ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean equals(@Nullable Object object) {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmLiteral.java#L76-L112","documentation":"When an SQM tree is rendered back to HQL (query-plan cache keys, diagnostics, criteria-to-HQL display), SqmLiteral.appendHqlString stringifies a non-null value through its JavaType. If the literal was constructed without a type (null JavaType), rendering is impossible and it throws IllegalArgumentException('Can't render value because java type is null').","triggerScenarios":"Constructing SqmLiteral (or a subclass) directly with a null SqmTypedNode/inherent type but a non-null value - new SqmLiteral<>(value, null, nodeBuilder) - and then triggering HQL rendering via createQuery, tree copy, or logging; also custom SqmExpression implementations whose getNodeType()/getJavaTypeDescriptor() returns null.","commonSituations":"Custom SQM node subclasses with lazy or missing types; literals created while a query is half-built; tree copies that drop type information; Hibernate upgrades changing when literal types get attached.","solutions":["Create literals through nodeBuilder().literal(value), which resolves the JavaType automatically.","When constructing SqmLiteral manually, always pass a non-null type, e.g. nodeBuilder().getTypeConfiguration().getBasicTypeForJavaType(value.getClass()).","In custom nodes, initialize the type eagerly (setExpressibleType) before the query is rendered."],"exampleFix":"// before\nnew SqmLiteral<>( value, null, nodeBuilder ); // appendHqlString later -> IllegalArgumentException\n\n// after\nnodeBuilder.literal( value );\n// or\nnew SqmLiteral<>( value, nodeBuilder.getTypeConfiguration().getBasicTypeForJavaType( value.getClass() ), nodeBuilder );","handlingStrategy":"validation","validationCode":"JavaType<?> jt = literal.getJavaTypeDescriptor();\nif ( literal.getLiteralValue() != null && jt == null ) {\n    throw new IllegalStateException( \"literal has no JavaType - rebuild it via nodeBuilder().literal(value)\" );\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use nodeBuilder().literal(...) instead of constructing SqmLiteral by hand.","Never pass a null inherent type when creating literal nodes.","In custom SQM nodes, set the expressible type eagerly before the query is rendered."],"tags":["hibernate","sqm","literal","hql-rendering","java-type"],"backgroundTag":"missing-type-information","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}