{"record":{"id":"8a92761f78e8ad23","repo":"hibernate/hibernate-orm","slug":"illegal-operator-for-temporal-type","errorCode":null,"errorMessage":"Illegal operator for temporal type: {}","messagePattern":"Illegal operator for temporal type: (.+?)","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java","lineNumber":7286,"sourceCode":"\t\t\t\t\tinferrableTypeAccessStack.pop();\n\t\t\t\t\tadjustmentScale = scale;\n\t\t\t\t\tnegativeAdjustment = negate;\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new SemanticException( \"Illegal operator for a duration \" + operator );\n\t\t}\n\t}\n\n\tprivate Object transformDatetimeArithmetic(SqmBinaryArithmetic<?> expression) {\n\t\tfinal var operator = expression.getOperator();\n\n\t\t// the only kind of algebra we know how to\n\t\t// do on dates/timestamps is subtract them,\n\t\t// producing a duration - all other binary\n\t\t// operator expressions with two dates or\n\t\t// timestamps are ill-formed\n\t\tif ( operator != SUBTRACT ) {\n\t\t\tthrow new SemanticException( \"Illegal operator for temporal type: \" + operator );\n\t\t}\n\n\t\t// a difference between two dates or two\n\t\t// timestamps is a leaf duration, so we\n\t\t// must apply the scale, and the 'by unit'\n\t\t// ts1 - ts2\n\n\t\tfinal var lhs = SqmExpressionHelper.getActualExpression( expression.getLeftHandOperand() );\n\t\tfinal var rhs = SqmExpressionHelper.getActualExpression( expression.getRightHandOperand() );\n\n\t\tfinal var fromClauseIndex = fromClauseIndexStack.getCurrent();\n\t\tinferrableTypeAccessStack.push( () -> determineValueMapping( rhs, fromClauseIndex ) );\n\t\tfinal var left = getActualExpression( cleanly( () -> toSqlExpression( lhs.accept( this ) ) ) );\n\t\tinferrableTypeAccessStack.pop();\n\t\tinferrableTypeAccessStack.push( () -> determineValueMapping( lhs, fromClauseIndex ) );\n\t\tfinal var right = getActualExpression( cleanly( () -> toSqlExpression( rhs.accept( this ) ) ) );\n\t\tinferrableTypeAccessStack.pop();\n","sourceCodeStart":7268,"sourceCodeEnd":7304,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java#L7268-L7304","documentation":"When both operands of a binary arithmetic expression are temporal (date/time/timestamp), the only defined operation is SUBTRACT, which produces a duration. Any other operator between two temporal values is ill-formed and rejected with a SemanticException naming the operator.","triggerScenarios":"HQL like 'date1 + date2', 'ts1 * ts2', or predicates where two mapped temporal attributes are combined with an operator other than minus.","commonSituations":"Naive date math ported from scripting languages; generated queries that apply the same arithmetic template to all numeric-looking columns; refactors that swap an operand from a number to a date column without changing the operator.","solutions":["Use subtraction for span calculations: 'date1 - date2'","Shift timestamps by durations instead: 'ts + 1 day'","Use dialect functions (add_months, dateadd...) via native SQL or function templates for other date combinations"],"exampleFix":"// before\nselect o.dueDate + o.createdOn from Ord o\n\n// after\nselect o.dueDate - o.createdOn from Ord o","handlingStrategy":"try-catch","validationCode":"if (isTemporalPath(left) && isTemporalPath(right) && operator != '-') {\n    throw new IllegalArgumentException(\"Only date1 - date2 is defined between two temporal values\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(hql).getResultList();\n} catch (org.hibernate.query.SemanticException e) {\n    log.error(\"Temporal operator rejected: {}\", hql, e);\n    throw e;\n}","preventionTips":["Use subtraction for spans and 'ts + duration' for shifts","Use dialect date functions for anything else","Type-check generated arithmetic against mapped attribute Java types"],"tags":["hibernate","hql","temporal","arithmetic","operator"],"backgroundTag":"temporal-arithmetic-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}