{"record":{"id":"20792ce77f2af331","repo":"hibernate/hibernate-orm","slug":"function-s-has-parameters-of-type-s-but-argum","errorCode":null,"errorMessage":"Function %s() has parameters of type %s, but argument of type %s given","messagePattern":"Function (.+?)\\(\\) has parameters of type (.+?), but argument of type (.+?) given","errorType":"exception","errorClass":"FunctionArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java","lineNumber":232,"sourceCode":"\t\t\t\t\tsig.append(\"arg\").append(i);\n\t\t\t\t}\n\t\t\t\tsig.append(\"])\");\n\t\t\t\treturn sig.toString();\n\t\t\t}\n\t\t};\n\t}\n\n\tpublic static ArgumentsValidator of(Class<?> javaType) {\n\t\treturn new ArgumentsValidator() {\n\t\t\t@Override\n\t\t\tpublic void validate(\n\t\t\t\t\tList<? extends SqmTypedNode<?>> arguments,\n\t\t\t\t\tString functionName,\n\t\t\t\t\tBindingContext bindingContext) {\n\t\t\t\tfor ( var argument : arguments ) {\n\t\t\t\t\tvar argType = argument.getNodeJavaType().getJavaTypeClass();\n\t\t\t\t\tif ( !javaType.isAssignableFrom( argType ) ) {\n\t\t\t\t\t\tthrow new FunctionArgumentException(\n\t\t\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\t\t\t\"Function %s() has parameters of type %s, but argument of type %s given\",\n\t\t\t\t\t\t\t\t\t\tfunctionName,\n\t\t\t\t\t\t\t\t\t\tjavaType.getName(),\n\t\t\t\t\t\t\t\t\t\targType.getName()\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tpublic static ArgumentsValidator composite(ArgumentsValidator... validators) {\n\t\treturn composite( asList( validators ) );\n\t}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardArgumentsValidators.java#L214-L250","documentation":"StandardArgumentsValidators.of(javaType) builds a validator that requires every argument of an HQL function call to be assignable to one Java class. During query parsing it inspects each SqmTypedNode's Java type (getNodeJavaType().getJavaTypeClass()) and throws FunctionArgumentException on the first argument not assignable to it. It is the type-safety net used by (mostly custom) function descriptors that accept exactly one Java type.","triggerScenarios":"A function registered with StandardArgumentsValidators.of(Integer.class) invoked with a String-typed path or literal, e.g. select my_num_func(p.name) where p.name is a String attribute; or binding a parameter with the wrong Java type (setString into a numeric-only function argument).","commonSituations":"Custom FunctionContributor descriptors written for one Java type then reused against differently-typed entity attributes; an entity field type changed (Integer to String) without updating queries; passing quoted literals ('1') where a numeric type is required.","solutions":["Pass an argument whose Java type is assignable to the required type - the message names the expected class and the actual class.","Rebind the parameter with the matching Java type or switch to the correctly typed entity attribute.","If the coercion is intentional, wrap the argument in an HQL cast(): cast(p.name as int).","If the function must accept several types, register it with a different validator (e.g. between(...) plus explicit cast handling) instead of of(Class)."],"exampleFix":"// before - descriptor registered with StandardArgumentsValidators.of(Integer.class)\nselect myNumFunc(p.name) from Person p\n\n// after - use the numeric attribute, or cast explicitly\nselect myNumFunc(p.age) from Person p\nselect myNumFunc(cast(p.name as int)) from Person p","handlingStrategy":"validation","validationCode":"// before creating the query, check the Java types you will bind\nstatic boolean allAssignableTo(Class<?> required, Class<?>... actual) {\n    for (Class<?> c : actual) {\n        if (!required.isAssignableFrom(c)) return false;\n    }\n    return true;\n}\nif (!allAssignableTo(Integer.class, String.class)) {\n    throw new IllegalArgumentException(\"myNumFunc requires Integer-typed arguments\");\n}","typeGuard":"static boolean hasJavaType(SqmTypedNode<?> node, Class<?> required) {\n    var jt = node.getNodeJavaType();\n    return jt != null && required.isAssignableFrom(jt.getJavaTypeClass());\n}","tryCatchPattern":"try {\n    em.createQuery(hql).getResultList();\n} catch (org.hibernate.query.sqm.produce.function.FunctionArgumentException e) {\n    // message names the expected and actual Java types\n    throw new IllegalArgumentException(\"Wrong argument type in HQL function call: \" + e.getMessage(), e);\n}","preventionTips":["Declare each custom function's accepted Java types next to its registration and assert bound parameter types against them.","Add one wrong-type test per custom function so type regressions surface in CI.","Prefer typed entity attributes over string literals in function arguments."],"tags":["hibernate","hql","sqm","function","type-check","arguments"],"backgroundTag":"function-argument-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}