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

  1. Convert the value to the exact id class first: ((Number) v).longValue(), UUID.fromString(s), etc.
  2. Standardize id types in DTOs/APIs (configure Jackson to emit longs, not ints)
  3. 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

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


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