hibernate/hibernate-orm · error · IllegalArgumentException

{} is not an entity

Error message

{} is not an entity

What it means

Thrown by PersistenceUnitUtilImpl.getPersister() as an IllegalArgumentException when theSessionFactory's mapping metamodel has no EntityPersister for the given class - i.e. the object passed to PersistenceUnitUtil.getIdentifier()/getVersion() is an instance of a class that is not a mapped entity in this persistence unit. Both the null-persister check and any MappingException during lookup are wrapped in this error.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/jpa/internal/PersistenceUnitUtilImpl.java:149

		}
	}

	private Object getIdentifierFromPersister(Object entity) {
		return getPersister( entity ).getIdentifier( entity );
	}

	private Object getVersionFromPersister(Object entity) {
		return getPersister( entity ).getVersion( entity );
	}

	private EntityPersister getPersister(Object entity) {
		final var entityClass = Hibernate.getClass( entity );
		try {
			final var entityPersister =
					sessionFactory.getMappingMetamodel()
							.getEntityDescriptor( entityClass );
			if ( entityPersister == null ) {
				throw new IllegalArgumentException( entityClass.getName() + " is not an entity" );
			}
			return entityPersister;
		}
		catch (MappingException ex) {
			throw new IllegalArgumentException( entityClass.getName() + " is not an entity", ex );
		}
	}

}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Register the class as an entity in the persistence unit (@Entity plus discoverable via scanning or listed in persistence.xml).
  2. Make sure you call the PersistenceUnitUtil of the EntityManagerFactory that actually maps that class.
  3. If you pass DTOs, do not route them through getIdentifier/getVersion - carry the id in the DTO explicitly.
  4. With exclude-unlisted-classes=true, add a <class> entry for every entity.

Example fix

<!-- before -->
<persistence-unit name="pu">
  <exclude-unlisted-classes>true</exclude-unlisted-classes>
  <!-- com.acme.Order missing -> getIdentifier(order) throws 'is not an entity' -->
</persistence-unit>

<!-- after -->
<persistence-unit name="pu">
  <exclude-unlisted-classes>true</exclude-unlisted-classes>
  <class>com.acme.Order</class>
</persistence-unit>
Defensive patterns

Strategy: type-guard

Validate before calling

// guard before calling PersistenceUnitUtil
if (!emf.getMetamodel().getEntities().stream()
        .map(e -> e.getJavaType())
        .anyMatch(t -> t.isAssignableFrom(entity.getClass()))) {
    throw new IllegalArgumentException(entity.getClass() + " is not mapped in this persistence unit");
}

Type guard

boolean isMappedEntity(EntityManagerFactory emf, Class<?> type) {
    try { return emf.getMetamodel().entity(type) != null; }
    catch (IllegalArgumentException e) { return false; }
}

Prevention

When it happens

Trigger: Calling getIdentifier()/getVersion() on a DTO, a plain POJO, a class mapped in a different SessionFactory, or an entity class whose mapping was never added (e.g. not listed in persistence.xml when <exclude-unlisted-classes>true</exclude-unlisted-classes>).

Common situations: Passing projections/DTOs from query results into JPA metadata helpers; multi-persistence-unit apps where the wrong EntityManagerFactory is used; entities living in a jar not scanned because unlisted classes are excluded; test fixtures instantiating unmapped copies of entity classes.

Related errors


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