hibernate/hibernate-orm · error · SemanticException
NATIVE is not a legal field for extract()
Error message
NATIVE is not a legal field for extract()
What it means
TemporalUnit.NATIVE is an internal marker used by dialects for dialect-specific extract fields (like Oracle's timezone_* parts); it is never a valid user-facing field. The ANSI ExtractFunction throws SemanticException as soon as an SQM extract() unit resolves to NATIVE, because there is no generic SQL rendering for it.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/ExtractFunction.java:98
final String pattern = dialect.extractPattern( unit );
new PatternRenderer( pattern ).render( sqlAppender, sqlAstArguments, walker );
}
@Override
protected <T> SelfRenderingSqmFunction generateSqmFunctionExpression(
List<? extends SqmTypedNode<?>> arguments,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine) {
final SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get( 0 );
final SqmExpression<?> originalExpression = (SqmExpression<?>) arguments.get( 1 );
final boolean compositeTemporal = SqmExpressionHelper.isCompositeTemporal( originalExpression );
final SqmExpression<?> expression = SqmExpressionHelper.getOffsetAdjustedExpression( originalExpression );
switch ( field.getUnit() ) {
case NANOSECOND:
return extractNanoseconds( expression, queryEngine );
case NATIVE:
throw new SemanticException("NATIVE is not a legal field for extract()");
case OFFSET:
if ( compositeTemporal ) {
final SqmPath<Object> offsetPath = ( (SqmPath<?>) originalExpression ).get(
ZONE_OFFSET_NAME
);
return new SelfRenderingSqmFunction<>(
this,
(sqlAppender, sqlAstArguments, returnType, walker) -> sqlAstArguments.get( 0 ).accept( walker ),
Collections.singletonList( offsetPath ),
null,
null,
StandardFunctionReturnTypeResolvers.useArgType( 1 ),
expression.nodeBuilder(),
"extract"
);
}
else {
// use format(arg, 'xxx') to get the offsetView on GitHub (pinned to fad1729dce)
Solutions
- Use a legal field: year, month, day, hour, minute, second, or the dialect-supported ones (quarter, week, epoch, day_of_week, ...)
- For dialect-specific parts, write a native query (e.g. Oracle EXTRACT(TIMEZONE_ABBR ...)) or register a custom function
- If you maintain a custom dialect, map native fields via a dedicated function descriptor instead of exposing NATIVE through extract()
Example fix
// before
Integer y = session.createQuery("select extract(native from e.ts) from Event e", Integer.class)...;
// after
Integer y = session.createQuery("select extract(year from e.ts) from Event e", Integer.class)...; Defensive patterns
Strategy: validation
Validate before calling
Set<TemporalUnit> LEGAL = EnumSet.range(YEAR, SECOND); // plus dialect extras
if (unit == TemporalUnit.NATIVE) throw new IllegalArgumentException("extract(native ...) is invalid"); Type guard
boolean isLegalExtractUnit(TemporalUnit u) { return u != TemporalUnit.NATIVE; } Try / catch
catch (SemanticException e) {
if (e.getMessage().contains("NATIVE")) {
throw new IllegalArgumentException("Rewrite query: use a supported extract field", e);
}
throw e;
} Prevention
- Validate extract() units against a whitelist when queries are built dynamically
- Use native queries for dialect-specific date parts
- Do not expose TemporalUnit.NATIVE through public query-builder APIs
When it happens
Trigger: HQL 'select extract(native from e.timestamp)' or criteria API extract(TemporalUnit.NATIVE, ...) reaching a dialect that uses the generic ExtractFunction rather than interpreting native units; also misusing an enum-mapped field whose name maps onto NATIVE in custom TemporalUnit extensions.
Common situations: Curiosity-driven or generated queries using unsupported fields; custom dialect work where TemporalUnit.NATIVE constants leak into user-visible criteria; upgrading from Hibernate 5 where some units were silently ignored.
Related errors
- Unrecognized field:
- unrecognized field: {unit}
- Unrecognized field: {unit}
- Temporal unit not supported [{}]
- Inverse distribution function '%s' must specify 'WITHIN GROU
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5da6f15cf4ef0780.
Report an issue: GitHub.