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 offset

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use a legal field: year, month, day, hour, minute, second, or the dialect-supported ones (quarter, week, epoch, day_of_week, ...)
  2. For dialect-specific parts, write a native query (e.g. Oracle EXTRACT(TIMEZONE_ABBR ...)) or register a custom function
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/5da6f15cf4ef0780. Report an issue: GitHub.