hibernate/hibernate-orm · error · IllegalArgumentException
Invalid duration unit:
Error message
Invalid duration unit:
What it means
renderInterval converts an HQL Duration (e.g. '4 day') into a SQL interval expression by mapping the duration's TemporalUnit to a target resolution the database understands (nanosecond->second, week->day, quarter->month). Duration units that are not actual time spans (EPOCH, DAY_OF_WEEK, DAY_OF_YEAR, OFFSET, TIMEZONE_HOUR, NATIVE, ...) have no interval equivalent, so this IllegalArgumentException is thrown.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java:7404
}
else {
duration.getMagnitude().accept( this );
// Convert to NANOSECOND because DurationJavaType requires values in that unit
appendSql( duration.getUnit().conversionFactor( NANOSECOND, dialect ) );
}
}
protected void renderInterval(Duration duration) {
final TemporalUnit unit = duration.getUnit();
appendSql( "(interval '1' " );
final TemporalUnit targetResolution = switch ( unit ) {
case NANOSECOND -> SECOND;
case SECOND, MINUTE, HOUR, DAY, MONTH, YEAR -> unit;
case WEEK -> DAY;
case QUARTER -> MONTH;
case DATE, TIME, EPOCH, DAY_OF_MONTH, DAY_OF_WEEK, DAY_OF_YEAR, WEEK_OF_MONTH, WEEK_OF_YEAR, OFFSET,
TIMEZONE_HOUR, TIMEZONE_MINUTE, NATIVE ->
throw new IllegalArgumentException( "Invalid duration unit: " + unit );
};
appendSql( targetResolution.toString() );
appendSql( '*' );
duration.getMagnitude().accept( this );
appendSql( duration.getUnit().conversionFactor( targetResolution, dialect ) );
appendSql( ')' );
}
protected void renderIntervalLiteral(Literal literal, TemporalUnit unit) {
final Number value = (Number) literal.getLiteralValue();
dialect.appendIntervalLiteral( this, switch ( unit ) {
case NANOSECOND -> java.time.Duration.ofNanos( value.longValue() );
case SECOND -> java.time.Duration.ofSeconds( value.longValue() );
case MINUTE -> java.time.Duration.ofMinutes( value.longValue() );
case HOUR -> java.time.Duration.ofHours( value.longValue() );
case DAY -> Period.ofDays( value.intValue() );
case WEEK -> Period.ofWeeks( value.intValue() );
case MONTH -> Period.ofMonths( value.intValue() );View on GitHub (pinned to fad1729dce)
Solutions
- Use span units for durations: second, minute, hour, day, week, month, quarter, year (nanosecond maps to second)
- Convert non-span units manually (e.g. day_of_year -> N * day)
- If you generate SQM programmatically, validate the Duration unit before rendering
Example fix
// before
session.createQuery("select e from Event e where e.time + 3 day_of_week < :t"); // invalid duration unit
// after
session.createQuery("select e from Event e where e.time + 21 day < :t"); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<TemporalUnit> SPAN_UNITS = Set.of(
TemporalUnit.NANOSECOND, TemporalUnit.SECOND, TemporalUnit.MINUTE, TemporalUnit.HOUR,
TemporalUnit.DAY, TemporalUnit.WEEK, TemporalUnit.MONTH, TemporalUnit.QUARTER, TemporalUnit.YEAR);
if (!SPAN_UNITS.contains(duration.getUnit())) {
throw new IllegalArgumentException("Not a duration unit: " + duration.getUnit());
} Type guard
boolean isSpanDurationUnit(TemporalUnit unit) {
return EnumSet.of(TemporalUnit.NANOSECOND, TemporalUnit.SECOND, TemporalUnit.MINUTE,
TemporalUnit.HOUR, TemporalUnit.DAY, TemporalUnit.WEEK, TemporalUnit.MONTH,
TemporalUnit.QUARTER, TemporalUnit.YEAR).contains(unit);
} Prevention
- Use only span units (second..year) in HQL duration arithmetic
- Convert extraction-style units (day_of_week, epoch) to plain multiples of day/second before use
- Validate user-supplied units against a whitelist before building queries
When it happens
Trigger: Duration arithmetic or interval rendering in HQL where the duration's unit is a non-span TemporalUnit - e.g. building a Duration with TemporalUnit.EPOCH/DAY_OF_WEEK via Criteria/HQL API (x + n epoch), or a custom function returning a Duration with such a unit that then gets rendered as an interval.
Common situations: HQL date/time arithmetic with exotic units (epoch, day_of_week, timezone_hour) that users expect to behave like durations; code constructing org.hibernate.query.sqm.tree.expression.Duration with wrong units; migrating Java java.time.temporal.ChronoUnit misuse into HQL.
Related errors
- Unrecognized field:
- unsupported duration unit: {unit}
- unrecognized field: {unit}
- Unrecognized field: {unit}
- Temporal unit not supported [{}]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c4ff917d155e3597.
Report an issue: GitHub.