{"record":{"id":"b6f6f723bb886caf","repo":"hibernate/hibernate-orm","slug":"unit-is-not-a-legal-field-b6f6f7","errorCode":null,"errorMessage":"{unit} is not a legal field","messagePattern":"(.+?) is not a legal field","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java","lineNumber":589,"sourceCode":"\t\t\t// an Interval\n\t\t\tpattern.append( \"age(?3,?2)\" );\n\t\t}\n\t\telse {\n\t\t\tswitch ( unit ) {\n\t\t\t\tcase YEAR:\n\t\t\t\tcase MONTH:\n\t\t\t\tcase QUARTER:\n\t\t\t\t\tpattern.append( \"age(?3,?2)\" );\n\t\t\t\t\tbreak;\n\t\t\t\tcase DAY:\n\t\t\t\tcase HOUR:\n\t\t\t\tcase MINUTE:\n\t\t\t\tcase SECOND:\n\t\t\t\tcase EPOCH:\n\t\t\t\t\tpattern.append( \"?3-?2\" );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new SemanticException( unit + \" is not a legal field\" );\n\t\t\t}\n\t\t}\n\t\tpattern.append( \")\" ).append( unit.conversionFactor( toUnit, this ) );\n\t}\n\n\t@Override\n\tpublic TimeZoneSupport getTimeZoneSupport() {\n\t\treturn TimeZoneSupport.NORMALIZE;\n\t}\n\n\t@Override\n\tpublic void initializeFunctionRegistry(FunctionContributions functionContributions) {\n\t\tsuper.initializeFunctionRegistry(functionContributions);\n\n\t\tCommonFunctionFactory functionFactory = new CommonFunctionFactory(functionContributions);\n\n\t\tfunctionFactory.cot();\n\t\tfunctionFactory.radians();","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java#L571-L607","documentation":"Legacy protected extractField() helper of PostgreSQLLegacyDialect used to compose date-difference patterns: year/month/quarter render as age(?3,?2) and day/hour/minute/second/epoch as (?3-?2). Any other TemporalUnit (for example WEEK) hits the default branch and throws SemanticException while the query is translated to SQL.","triggerScenarios":"HQL timestampdiff()/date subtraction whose unit is routed through the legacy extractField path and is not year/month/quarter/day/hour/minute/second/epoch, on PostgreSQLLegacyDialect.","commonSituations":"Same family as the other unit failures: generic date-math utilities or ported queries using non-standard units.","solutions":["Restrict units to the supported set and scale manually (week -> day / 7)","Compute date differences in the application layer","Use the modern PostgreSQLDialect","Native query fallback"],"exampleFix":"-- before\nselect timestampdiff(week, o.startTs, o.endTs) from Order o\n\n-- after\nselect timestampdiff(day, o.startTs, o.endTs) / 7 from Order o","handlingStrategy":"validation","validationCode":"private static final Set<TemporalUnit> PG_EXTRACT_UNITS = EnumSet.of(\n        TemporalUnit.YEAR, TemporalUnit.MONTH, TemporalUnit.QUARTER, TemporalUnit.DAY,\n        TemporalUnit.HOUR, TemporalUnit.MINUTE, TemporalUnit.SECOND, TemporalUnit.EPOCH );\n\nif ( !PG_EXTRACT_UNITS.contains( unit ) ) {\n    unit = TemporalUnit.DAY;\n}","typeGuard":"static boolean pgExtractFieldSupports(TemporalUnit unit) {\n    return EnumSet.of( TemporalUnit.YEAR, TemporalUnit.MONTH, TemporalUnit.QUARTER, TemporalUnit.DAY,\n                       TemporalUnit.HOUR, TemporalUnit.MINUTE, TemporalUnit.SECOND,\n                       TemporalUnit.EPOCH ).contains( unit );\n}","tryCatchPattern":"try {\n    return query.list();\n}\ncatch ( SemanticException e ) {\n    // legacy extractField path rejected the unit: degrade to day and scale\n    throw e;\n}","preventionTips":["Avoid week/day-of-week units in HQL date differences","Compute exotic granularities in Java","Prefer the modern PostgreSQLDialect for new code"],"tags":["postgresql","hql","temporal-unit","query-translation"],"backgroundTag":"unsupported-temporal-unit","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}