{"record":{"id":"81f27ed3475aa485","repo":"hibernate/hibernate-orm","slug":"start-and-stop-parameters-of-function-s-must","errorCode":null,"errorMessage":"Start and stop parameters of function '%s()' must be of the same type, but found [%s,%s]","messagePattern":"Start and stop parameters of function '(.+?)\\(\\)' must be of the same type, but found \\[(.+?),(.+?)\\]","errorType":"exception","errorClass":"FunctionArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/function/GenerateSeriesArgumentValidator.java","lineNumber":55,"sourceCode":"\t\tfinal var step = arguments.size() > 2 ? arguments.get( 2 ) : null;\n\n\t\tfinal var startExpressible = start.getExpressible();\n\t\tfinal var stopExpressible = stop.getExpressible();\n\t\tfinal var stepExpressible = step == null ? null : step.getExpressible();\n\n\t\tfinal var startType = startExpressible == null ? null : startExpressible.getSqmType();\n\t\tfinal var stopType = stopExpressible == null ? null : stopExpressible.getSqmType();\n\t\tfinal var stepType = stepExpressible == null ? null : stepExpressible.getSqmType();\n\n\t\tif ( startType == null ) {\n\t\t\tthrow unknownType( functionName, arguments, 0 );\n\t\t}\n\t\tif ( stopType == null ) {\n\t\t\tthrow unknownType( functionName, arguments, 1 );\n\t\t}\n\n\t\tif ( startType != stopType ) {\n\t\t\tthrow new FunctionArgumentException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\"Start and stop parameters of function '%s()' must be of the same type, but found [%s,%s]\",\n\t\t\t\t\t\t\tfunctionName,\n\t\t\t\t\t\t\tstartType.getTypeName(),\n\t\t\t\t\t\t\tstopType.getTypeName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\tfinal var type = (JdbcMapping) startType;\n\t\tfinal var jdbcType = type.getJdbcType();\n\t\tif ( jdbcType.isInteger() || jdbcType.isDecimal() ) {\n\t\t\tif ( step != null ) {\n\t\t\t\tif ( stepType == null ) {\n\t\t\t\t\tthrow unknownType( functionName, arguments, 2 );\n\t\t\t\t}\n\t\t\t\tif ( stepType != startType ) {\n\t\t\t\t\tthrow new FunctionArgumentException(\n\t\t\t\t\t\t\tString.format(","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/function/GenerateSeriesArgumentValidator.java#L37-L73","documentation":"GenerateSeriesArgumentValidator requires the start and stop arguments of generate_series() to resolve to the exact same SqmType. Unlike native PostgreSQL, the HQL emulation cannot implicitly unify mixed types (int vs long, timestamp vs date, varchar), so mismatches fail fast with the two type names printed.","triggerScenarios":"HQL such as generate_series(1, 10L), generate_series(timestampLiteral, dateLiteral), or generate_series(:start, :stop) where the two bind parameters were assigned slightly different Java types (e.g. LocalDateTime vs OffsetDateTime, Integer vs Long).","commonSituations":"Dynamic query builders binding parameters with inconsistent Java types; porting PostgreSQL SQL to HQL where implicit casts made it work; entity fields of different temporal types fed into one series.","solutions":["Make both arguments the same Java/domain type: cast in HQL (generate_series(1, cast(10 as integer))) or normalize bind parameter types in Java","For temporal ranges, use one type end-to-end, e.g. both LocalDateTime or both OffsetDateTime","Bind explicit typed parameters: setParameter(\"start\", start, LocalDateTime.class) on both sides"],"exampleFix":"// before\nq = session.createQuery(\"select gs from generate_series(:a, :b) gs\")\n            .setParameter(\"a\", 1)\n            .setParameter(\"b\", 10L); // Integer vs Long -> error\n\n// after\nq = session.createQuery(\"select gs from generate_series(:a, :b) gs\")\n            .setParameter(\"a\", 1)\n            .setParameter(\"b\", 10); // both Integer","handlingStrategy":"type-guard","validationCode":"// normalize bounds before building the query\nif (!start.getClass().equals(stop.getClass())) {\n    throw new IllegalArgumentException(\"generate_series bounds must share one type: \"\n        + start.getClass().getSimpleName() + \" vs \" + stop.getClass().getSimpleName());\n}","typeGuard":"boolean sameSeriesType(Object a, Object b) {\n    return a != null && b != null && a.getClass() == b.getClass();\n}","tryCatchPattern":"catch (FunctionArgumentException e) {\n    throw new IllegalArgumentException(\"Mismatched generate_series bound types in query\", e);\n}","preventionTips":["Bind both bound parameters with explicit type: setParameter(\"a\", v, Long.class), setParameter(\"b\", w, Long.class)","Wrap generate_series usage in one typed repository helper","Add a query-building unit test asserting bound types match"],"tags":["hibernate","hql","generate-series","type-mismatch","function-validation"],"backgroundTag":"hql-function-argument-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}