hibernate/hibernate-orm · error · IllegalArgumentException
Unsure how to handle given Java type [{}] as TemporalType#TI
Error message
Unsure how to handle given Java type [{}] as TemporalType#TIMESTAMP What it means
When a parameter is bound with TemporalType.TIMESTAMP, BindingTypeHelper.resolveTimestampTemporalTypeVariant maps the parameter's Java type to a TIMESTAMP-capable basic type (BindingTypeHelper.java:123-146). It handles java.util.Date, Calendar, LocalDateTime, Instant, OffsetDateTime, ZonedDateTime and OffsetTime; any other class falls through to this IllegalArgumentException naming the unsupported Java type.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/internal/BindingTypeHelper.java:143
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.CALENDAR );
}
else if ( java.util.Date.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.TIMESTAMP );
}
else if ( Instant.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INSTANT );
}
else if ( OffsetDateTime.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.OFFSET_DATE_TIME );
}
else if ( ZonedDateTime.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.ZONED_DATE_TIME );
}
else if ( OffsetTime.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.OFFSET_TIME );
}
else {
throw new IllegalArgumentException( "Unsure how to handle given Java type ["
+ javaType.getName() + "] as TemporalType#TIMESTAMP" );
}
}
private static BindableType<?> resolveDateTemporalTypeVariant(
Class<?> javaType,
BindableType<?> baseType,
TypeConfiguration typeConfiguration) {
if ( baseType.getJavaType().isAssignableFrom( javaType ) ) {
return baseType;
}
else if ( Calendar.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.CALENDAR_DATE );
}
else if ( java.util.Date.class.isAssignableFrom( javaType ) ) {
return typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DATE );
}
else if ( Instant.class.isAssignableFrom( javaType ) ) {View on GitHub (pinned to fad1729dce)
Solutions
- Drop the TemporalType argument entirely - Hibernate already maps LocalDate/LocalTime/LocalDateTime correctly without it.
- Use TemporalType.DATE for LocalDate, TemporalType.TIME for LocalTime, and reserve TemporalType.TIMESTAMP for LocalDateTime/Instant/OffsetDateTime/ZonedDateTime/Date/Calendar.
- Convert the value: value.atStartOfDay() for LocalDate, value.atDate(...) for LocalTime, before binding with TIMESTAMP precision.
Example fix
// before - LocalDate cannot be bound as TIMESTAMP
query.setParameter("ts", LocalDate.now(), TemporalType.TIMESTAMP);
// after - either let Hibernate infer
query.setParameter("ts", LocalDate.now());
// or convert to a TIMESTAMP-capable type
query.setParameter("ts", LocalDate.now().atStartOfDay()); Defensive patterns
Strategy: type-guard
Validate before calling
static final Set<Class<?>> TIMESTAMP_OK = Set.of(
java.util.Date.class, java.util.Calendar.class,
java.time.LocalDateTime.class, java.time.Instant.class,
java.time.OffsetDateTime.class, java.time.ZonedDateTime.class,
java.time.OffsetTime.class );
if ( !TIMESTAMP_OK.contains( value.getClass() ) ) {
throw new IllegalArgumentException( "Bind " + value.getClass().getSimpleName()
+ " without TemporalType, or convert to a timestamp-capable type" );
} Type guard
static boolean supportsTimestampPrecision(Object v) {
return v instanceof java.util.Date || v instanceof java.util.Calendar
|| v instanceof java.time.LocalDateTime || v instanceof java.time.Instant
|| v instanceof java.time.OffsetDateTime || v instanceof java.time.ZonedDateTime
|| v instanceof java.time.OffsetTime;
} Prevention
- Map TemporalType.DATE->LocalDate, TIME->LocalTime/OffsetTime, TIMESTAMP->LocalDateTime/Instant/OffsetDateTime/ZonedDateTime/Date/Calendar.
- Prefer omitting the TemporalType argument for java.time types.
- Centralize temporal binding in one helper that applies the compatibility table.
When it happens
Trigger: Query.setParameter('ts', LocalDate.now(), TemporalType.TIMESTAMP) - LocalDate has no TIMESTAMP variant; passing LocalTime, YearMonth, java.sql.Date subclasses outside the handled set, or a custom temporal-ish class with TemporalType.TIMESTAMP; stored-procedure parameters bound the same way.
Common situations: Migrating fields from java.util.Date to java.time types while keeping old TemporalType.TIMESTAMP arguments; code written for one temporal family (LocalDate) reused with precision meant for another (TIMESTAMP).
Related errors
- Cannot treat non-temporal parameter type with temporal preci
- Unsure how to handle given Java type [{}] as TemporalType#DA
- Unsure how to handle given Java type [{}] as TemporalType#TI
- The parameter [{param}] is not part of this Query
- Unable to determine JDBC type for converted parameter relati
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/4e0127e6dac3817a.
Report an issue: GitHub.