hibernate/hibernate-orm · error · UnsupportedOperationException

getTypeName() + " as TemporalType.TIMESTAMP not supported"

Error message

getTypeName() + " as TemporalType.TIMESTAMP not supported"

What it means

AbstractTemporalJavaType.resolveTypeForPrecision routes a TemporalType.TIMESTAMP request to forTimestampPrecision, which by default throws UnsupportedOperationException. Only descriptors that support timestamp precision (JdbcTimestampJavaType, DateJavaType, CalendarJavaType, OffsetDateTimeJavaType, etc.) override it; a temporal Java type that has no timestamp representation fails here.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractTemporalJavaType.java:56

			TypeConfiguration typeConfiguration) {
		if ( precision == null ) {
			return forMissingPrecision( typeConfiguration );
		}
		else {
			return switch ( precision ) {
				case DATE -> forDatePrecision( typeConfiguration );
				case TIME -> forTimePrecision( typeConfiguration );
				case TIMESTAMP -> forTimestampPrecision( typeConfiguration );
			};
		}
	}

	private TemporalJavaType<T> forMissingPrecision(TypeConfiguration typeConfiguration) {
		return this;
	}

	protected TemporalJavaType<T> forTimestampPrecision(TypeConfiguration typeConfiguration) {
		throw new UnsupportedOperationException(
				getTypeName() + " as TemporalType.TIMESTAMP not supported"
		);
	}

	protected TemporalJavaType<T> forDatePrecision(TypeConfiguration typeConfiguration) {
		throw new UnsupportedOperationException(
				getTypeName() + " as TemporalType.DATE not supported"
		);
	}

	protected TemporalJavaType<T> forTimePrecision(TypeConfiguration typeConfiguration) {
		throw new UnsupportedOperationException(
				getTypeName() + " as TemporalType.TIME not supported"
		);
	}

	@Override
	public String toString() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Align the annotation with the type: LocalDate/@Temporal is invalid - drop @Temporal on java.time fields
  2. Use java.util.Date or java.util.Calendar if one field must work with DATE, TIME and TIMESTAMP precisions
  3. Change the field to a timestamp-capable type (LocalDateTime, OffsetDateTime, Instant, java.util.Date) when TIMESTAMP semantics are needed
  4. Remove programmatic timestamp-precision requests for time-only/date-only types

Example fix

// before
@Entity
public class Event {
    @Temporal(TemporalType.TIMESTAMP) // invalid for LocalTime
    private LocalTime startTime;
}
// after
@Entity
public class Event {
    private LocalTime startTime; // no @Temporal; stored as TIME
    private LocalDateTime occurredAt; // timestamp semantics
}
Defensive patterns

Strategy: validation

Validate before calling

// startup audit: @Temporal only on java.util.Date/Calendar, and precision must fit the type
for (Field f : entity.getDeclaredFields()) {
    Temporal t = f.getAnnotation(Temporal.class);
    if (t == null) continue;
    Class<?> ft = f.getType();
    if (t.value() == TemporalType.TIMESTAMP
            && !Date.class.isAssignableFrom(ft) && !Calendar.class.isAssignableFrom(ft)
            && ft != LocalDateTime.class && ft != OffsetDateTime.class && ft != Instant.class) {
        throw new MappingException("TIMESTAMP precision invalid for " + ft);
    }
}

Type guard

static boolean supportsTimestampPrecision(Class<?> fieldType) {
    return Date.class.isAssignableFrom(fieldType) || Calendar.class.isAssignableFrom(fieldType)
        || fieldType == LocalDateTime.class || fieldType == OffsetDateTime.class
        || fieldType == Instant.class || fieldType == ZonedDateTime.class
        || fieldType == java.sql.Timestamp.class;
}

Try / catch

try {
    return session.find(Event.class, id);
} catch (UnsupportedOperationException e) {
    if (String.valueOf(e.getMessage()).contains("as TemporalType.TIMESTAMP not supported")) {
        // mapping bug, not data: fix @Temporal/field type and redeploy - do not retry
        throw new MappingException("Fix temporal mapping on Event.startTime", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Asking Hibernate to treat a temporal type as TIMESTAMP when its descriptor does not support it - e.g. @Temporal(TemporalType.TIMESTAMP) on a java.sql.Time / java.time.LocalTime / java.time.LocalDate field (LocalTimeJavaType and LocalDateJavaType override only their own precision), or programmatic/basic-type requests with timestamp precision.

Common situations: Copy-pasted @Temporal annotations mismatched with the field type; migrating fields between java.util.Date (supports all precisions) and java.time types (each supports one precision); legacy mappings using JdbcDate/JdbcTime descriptors with a different @Temporal value; JPA spec note that @Temporal applies to java.util.Date/Calendar only.

Related errors


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