hibernate/hibernate-orm · error · SemanticException
Illegal operator for a duration {}
Error message
Illegal operator for a duration {} What it means
transformDurationArithmetic handles only duration algebra with ADD, SUBTRACT and MULTIPLY-with-scalar-on-the-left; any other operator hitting the switch default throws this SemanticException. Effectively: durations can be added/subtracted and scaled by a scalar, but not divided, modulo'd, or multiplied by another duration.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java:7273
// -x * (d1 - d2) => - x * d1 + x * d2
inferrableTypeAccessStack.push( () -> determineValueMapping( rhs, fromClauseIndex ) );
final Expression duration = toSqlExpression( lhs.accept( this ) );
inferrableTypeAccessStack.pop();
final Expression scale = adjustmentScale;
final boolean negate = negativeAdjustment;
adjustmentScale = applyScale( duration );
negativeAdjustment = false; //was sucked into the scale
try {
inferrableTypeAccessStack.push( () -> determineValueMapping( lhs, fromClauseIndex ) );
return rhs.accept( this );
}
finally {
inferrableTypeAccessStack.pop();
adjustmentScale = scale;
negativeAdjustment = negate;
}
default:
throw new SemanticException( "Illegal operator for a duration " + operator );
}
}
private Object transformDatetimeArithmetic(SqmBinaryArithmetic<?> expression) {
final var operator = expression.getOperator();
// the only kind of algebra we know how to
// do on dates/timestamps is subtract them,
// producing a duration - all other binary
// operator expressions with two dates or
// timestamps are ill-formed
if ( operator != SUBTRACT ) {
throw new SemanticException( "Illegal operator for temporal type: " + operator );
}
// a difference between two dates or two
// timestamps is a leaf duration, so we
// must apply the scale, and the 'by unit'View on GitHub (pinned to fad1729dce)
Solutions
- Express division of a duration as multiplication by a fraction: 'dur * 0.5'
- Extract a scalar first (e.g. via 'extract(epoch from ...)' style functions) and do plain numeric math
- Move the operation so the duration only ever appears with +, -, or scalar *
Example fix
// before select (o.closedAt - o.openedAt) / 2 from Ord o // after select (o.closedAt - o.openedAt) * 0.5 from Ord o
Defensive patterns
Strategy: try-catch
Validate before calling
if (isDurationExpr(operand) && (operator == '/' || operator == '%' )) {
throw new IllegalArgumentException("Duration supports only +, - and scalar *; use dur * 0.5");
} Try / catch
try {
return session.createQuery(hql).getResultList();
} catch (org.hibernate.query.SemanticException e) {
log.error("Illegal duration operator in {}: {}", hql, e.getMessage());
throw e;
} Prevention
- Use multiplication by a fraction instead of dividing durations
- Extract scalars with functions for ratio math
- Keep durations only in +/-/scalar-* positions in generated expressions
When it happens
Trigger: HQL dividing a duration ('(ts1 - ts2) / 2' after normalization in some versions), applying modulo to a duration, or multiplying two duration expressions together; negated duration constructs that fall through to an unhandled operator.
Common situations: Computing averages or ratios of time spans in report queries; porting SQL like 'datediff(...) / 7' to HQL duration syntax; refactors that change operand order so the duration lands under an unsupported operator.
Related errors
- Scalar multiplication of temporal value
- Illegal operator for temporal type: {}
- Invalid duration unit:
- Insert conflict 'do update' clause with constraint name is n
- field type not supported on Derby: " + unit
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/06fd8c109d9ae50f.
Report an issue: GitHub.