hibernate/hibernate-orm · error · IllegalArgumentException
Not an instance of id type " + idType.getName()
Error message
Not an instance of id type " + idType.getName()
What it means
EntityJavaType.wrap() turns an identifier value back into an entity via internalLoad(). It first checks the supplied value is an instance of the entity's identifier class (persister.getIdentifierType().getReturnedClass()); passing an Integer where the id is Long, a Long where it is UUID, or a String for a numeric id throws IllegalArgumentException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EntityJavaType.java:81
final var id =
options.getSessionFactory().getMappingMetamodel()
.getEntityDescriptor( getJavaTypeClass() )
.getIdentifier( value );
if ( !type.isInstance( id ) ) {
throw new IllegalArgumentException( "Id not an instance of type " + type.getName() );
}
return type.cast( value );
}
@Override
public <X> T wrap(X value, WrapperOptions options) {
final var entityClass = getJavaTypeClass();
final var persister =
options.getSessionFactory().getMappingMetamodel()
.getEntityDescriptor( entityClass );
final var idType = persister.getIdentifierType().getReturnedClass();
if ( !idType.isInstance( value ) ) {
throw new IllegalArgumentException( "Not an instance of id type " + idType.getName() );
}
final var entity =
options.getSession()
.internalLoad( persister.getEntityName(), value, false, true );
return entityClass.cast( entity );
}
@Override
public String toString() {
return "EntityJavaType(" + getTypeName() + ")";
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Convert the value to the exact id class first: ((Number) v).longValue(), UUID.fromString(s), etc.
- Standardize id types in DTOs/APIs (configure Jackson to emit longs, not ints)
- Fix the mapping so the declared id class matches what producers actually send
Example fix
// before
Object id = mapNode.get("id"); // Integer from JSON
session.createQuery("from Owner o where o.id = :id", Owner.class)
.setParameter("id", id); // Owner.id is Long -> Integer not an instance -> throws
// after
long id = ((Number) mapNode.get("id")).longValue();
session.createQuery("from Owner o where o.id = :id", Owner.class)
.setParameter("id", id); Defensive patterns
Strategy: type-guard
Validate before calling
static Object normalizeId(Class<?> idClass, Object raw) {
if (idClass == Long.class && raw instanceof Number n) return n.longValue();
if (idClass == Integer.class && raw instanceof Number n) return n.intValue();
if (idClass == java.util.UUID.class && raw instanceof String s) return java.util.UUID.fromString(s);
return raw;
}
// apply before passing ids into session operations or typed queries Type guard
static boolean isEntityIdValue(SessionFactory sf, Class<?> entity, Object v) {
return sf.getMappingMetamodel().getEntityDescriptor(entity)
.getIdentifierType().getReturnedClass().isInstance(v);
} Try / catch
try {
Owner o = session.byId(Owner.class).load(rawId);
} catch (IllegalArgumentException e) {
// wrong id runtime type: coerce to the declared id class, then retry
Owner o = session.byId(Owner.class).load(normalizeId(Owner.class.getDeclaredIdClass(), rawId));
} Prevention
- Configure JSON deserializers to emit the declared id type (longs, not ints)
- Centralize id conversion helpers instead of ad-hoc casts
- Audit API DTOs: id fields must match entity @Id types exactly
When it happens
Trigger: Wrapping/coercing an id of the wrong Java type; hydration paths (query result assembly, cache materialization) feeding raw JDBC or JSON values into entity wrapping without normalizing numeric types; passing '5' as String for a Long id.
Common situations: JSON payloads delivering ids as Integer (Jackson's small-number default) into Long-id entities; switching id generation strategy or type; heterogeneous id types across an inheritance hierarchy; JavaScript front-ends sending numbers where UUIDs are expected.
Related errors
- Identifier property '" + getPath( holder, data ) + "' cannot
- Identifier attribute '%s' of entity '%s' has type '%s' but i
- identifier mapping has wrong number of columns: " + getEntit
- Unknown wrap conversion requested: " + conversionType.getNam
- Wrap strategy not known for this Java type: " + getTypeName(
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1eb01fa142b4ae1c.
Report an issue: GitHub.