{"record":{"id":"c4ff917d155e3597","repo":"hibernate/hibernate-orm","slug":"invalid-duration-unit","errorCode":null,"errorMessage":"Invalid duration unit: ","messagePattern":"Invalid duration unit: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java","lineNumber":7404,"sourceCode":"\t\t}\n\t\telse {\n\t\t\tduration.getMagnitude().accept( this );\n\t\t\t// Convert to NANOSECOND because DurationJavaType requires values in that unit\n\t\t\tappendSql( duration.getUnit().conversionFactor( NANOSECOND, dialect ) );\n\t\t}\n\t}\n\n\tprotected void renderInterval(Duration duration) {\n\t\tfinal TemporalUnit unit = duration.getUnit();\n\t\tappendSql( \"(interval '1' \" );\n\t\tfinal TemporalUnit targetResolution = switch ( unit ) {\n\t\t\tcase NANOSECOND -> SECOND;\n\t\t\tcase SECOND, MINUTE, HOUR, DAY, MONTH, YEAR -> unit;\n\t\t\tcase WEEK -> DAY;\n\t\t\tcase QUARTER -> MONTH;\n\t\t\tcase DATE, TIME, EPOCH, DAY_OF_MONTH, DAY_OF_WEEK, DAY_OF_YEAR, WEEK_OF_MONTH, WEEK_OF_YEAR, OFFSET,\n\t\t\t\tTIMEZONE_HOUR, TIMEZONE_MINUTE, NATIVE ->\n\t\t\t\t\tthrow new IllegalArgumentException( \"Invalid duration unit: \" + unit );\n\t\t};\n\t\tappendSql( targetResolution.toString() );\n\t\tappendSql( '*' );\n\t\tduration.getMagnitude().accept( this );\n\t\tappendSql( duration.getUnit().conversionFactor( targetResolution, dialect ) );\n\t\tappendSql( ')' );\n\t}\n\n\tprotected void renderIntervalLiteral(Literal literal, TemporalUnit unit) {\n\t\tfinal Number value = (Number) literal.getLiteralValue();\n\t\tdialect.appendIntervalLiteral( this, switch ( unit ) {\n\t\t\tcase NANOSECOND -> java.time.Duration.ofNanos( value.longValue() );\n\t\t\tcase SECOND -> java.time.Duration.ofSeconds( value.longValue() );\n\t\t\tcase MINUTE -> java.time.Duration.ofMinutes( value.longValue() );\n\t\t\tcase HOUR -> java.time.Duration.ofHours( value.longValue() );\n\t\t\tcase DAY -> Period.ofDays( value.intValue() );\n\t\t\tcase WEEK -> Period.ofWeeks( value.intValue() );\n\t\t\tcase MONTH -> Period.ofMonths( value.intValue() );","sourceCodeStart":7386,"sourceCodeEnd":7422,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java#L7386-L7422","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nsession.createQuery(\"select e from Event e where e.time + 3 day_of_week < :t\"); // invalid duration unit\n\n// after\nsession.createQuery(\"select e from Event e where e.time + 21 day < :t\");","handlingStrategy":"validation","validationCode":"private static final Set<TemporalUnit> SPAN_UNITS = Set.of(\n        TemporalUnit.NANOSECOND, TemporalUnit.SECOND, TemporalUnit.MINUTE, TemporalUnit.HOUR,\n        TemporalUnit.DAY, TemporalUnit.WEEK, TemporalUnit.MONTH, TemporalUnit.QUARTER, TemporalUnit.YEAR);\n\nif (!SPAN_UNITS.contains(duration.getUnit())) {\n    throw new IllegalArgumentException(\"Not a duration unit: \" + duration.getUnit());\n}","typeGuard":"boolean isSpanDurationUnit(TemporalUnit unit) {\n    return EnumSet.of(TemporalUnit.NANOSECOND, TemporalUnit.SECOND, TemporalUnit.MINUTE,\n            TemporalUnit.HOUR, TemporalUnit.DAY, TemporalUnit.WEEK, TemporalUnit.MONTH,\n            TemporalUnit.QUARTER, TemporalUnit.YEAR).contains(unit);\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["hibernate","hql","duration","interval","temporal-unit"],"backgroundTag":"duration-unit-invalid","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}