hibernate/hibernate-orm · error · SemanticException

Unrecognized field:

Error message

Unrecognized field: 

What it means

GaussDBDialect.timestampdiffPattern builds the SQL for HQL timestampdiff(unit, a, b) and for duration differences. It explicitly implements YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, NANOSECOND and NATIVE via extract() over the interval; any other TemporalUnit falls into the default branch and throws SemanticException ('Unrecognized field: <unit>'), because GaussDB's extract() cannot handle that unit over a duration.

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java:529

	}

	@Override @SuppressWarnings("deprecation")
	public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) {
		if ( unit == null ) {
			return "(?3-?2)";
		}
		return switch (unit) {
			case YEAR -> "extract(year from ?3-?2)";
			case QUARTER -> "(extract(year from ?3-?2)*4+extract(month from ?3-?2)/3)";
			case MONTH -> "(extract(year from ?3-?2)*12+extract(month from ?3-?2))";
			case WEEK -> "(extract(day from ?3-?2)/7)"; // week is not supported by extract() when the argument is a duration
			case DAY -> "extract(day from ?3-?2)";
			// in order to avoid multiple calls to extract(),
			// we use extract(epoch from x - y) * factor for
			// all the following units:
			case HOUR, MINUTE, SECOND, NANOSECOND, NATIVE ->
					"extract(epoch from ?3-?2)" + EPOCH.conversionFactor( unit, this );
			default -> throw new SemanticException( "Unrecognized field: " + unit );
		};
	}

	@Override
	public TimeZoneSupport getTimeZoneSupport() {
		return TimeZoneSupport.NORMALIZE;
	}

	@Override
	public void initializeFunctionRegistry(FunctionContributions functionContributions) {
		super.initializeFunctionRegistry(functionContributions);

		GaussDBFunctionRegistry functionRegistry = new GaussDBFunctionRegistry( functionContributions );
		functionRegistry.register();
	}

	@Override
	public @Nullable String getDefaultOrdinalityColumnName() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rewrite the difference using a supported unit and convert in HQL or Java: timestampdiff(year, d1, d2) / 10 instead of decade
  2. Compute the duration in a supported base unit (epoch seconds via SECOND or NATIVE) and derive the exotic unit in Java
  3. Use a native query with GaussDB-compatible extract() expressions for the rare exotic-unit cases
  4. Normalize all timestampdiff calls in shared query code to the supported unit set {year, quarter, month, week, day, hour, minute, second, nanosecond}

Example fix

// before (HQL, throws on GaussDB)
long decades = session.createQuery("select timestampdiff(decade, p.start, p.end) from Period p", Long.class).getSingleResult();

// after (supported unit + Java conversion)
long years = session.createQuery("select timestampdiff(year, p.start, p.end) from Period p", Long.class).getSingleResult();
long decades = years / 10;
Defensive patterns

Strategy: validation

Validate before calling

static final Set<TemporalUnit> GAUSS_DIFF_UNITS = EnumSet.of(
    TemporalUnit.YEAR, TemporalUnit.QUARTER, TemporalUnit.MONTH, TemporalUnit.WEEK,
    TemporalUnit.DAY, TemporalUnit.HOUR, TemporalUnit.MINUTE, TemporalUnit.SECOND,
    TemporalUnit.NANOSECOND, TemporalUnit.NATIVE);

if (!GAUSS_DIFF_UNITS.contains(unit)) {
    unit = normalizeToSupported(unit); // decade -> year, divide by 10 afterwards
}

Type guard

static boolean timestampdiffUnitSafe(Dialect d, TemporalUnit unit) {
    return !(d instanceof GaussDBDialect) || GAUSS_DIFF_UNITS.contains(unit);
}

Try / catch

try {
    v = session.createQuery("select timestampdiff(" + unit.name() + ", a, b) ...", Long.class).getSingleResult();
} catch (org.hibernate.query.SemanticException e) {
    if (e.getMessage().startsWith("Unrecognized field")) {
        // re-express in a base unit (year/second) and convert in Java
    } else throw e;
}

Prevention

When it happens

Trigger: HQL 'timestampdiff(decade, d1, d2)' or duration unit arithmetic using units outside the supported set (e.g. decade, century, millennium, or date-part fields like day_of_week used as a diff unit), executed with the GaussDB dialect. Equivalent constructs like 'x by decade' duration literals hit the same pattern.

Common situations: Porting HQL written for PostgreSQLDialect, whose timestampdiffPattern covers more units, to GaussDB; queries computing long-horizon differences (decades/centuries) in reporting code; unit tests that iterate over every TemporalUnit.

Related errors


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