hibernate/hibernate-orm · error · IllegalArgumentException

Entity '{}' is not a dynamic entity

Error message

Entity '{}' is not a dynamic entity

What it means

EntityGraphs.createGraphForDynamicEntity(EntityType) builds a graph for dynamic-map entities — entities mapped without a Java class (RepresentationMode.MAP), whose attributes are held in a Map<String,?>. Passing a regular POJO-mapped EntityType (RepresentationMode.POJO) throws IllegalArgumentException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/graph/EntityGraphs.java:68

		return new RootGraphImpl<>( null, (EntityDomainType<T>) rootType );
	}

	/**
	 * Create a new entity graph rooted at the given
	 * {@linkplain RepresentationMode#MAP dynamic entity}, without
	 * needing a reference to the session or session factory.
	 *
	 * @param rootType The {@link EntityType} representing the root
	 *                 entity of the graph, which must be a dynamic
	 *                 entity
	 * @return a new mutable {@link EntityGraph}
	 *
	 * @since 7.0
	 */
	public static EntityGraph<Map<String,?>> createGraphForDynamicEntity(EntityType<?> rootType) {
		final var domainType = (EntityDomainType<?>) rootType;
		if ( domainType.getRepresentationMode() != RepresentationMode.MAP ) {
			throw new IllegalArgumentException( "Entity '" + domainType.getHibernateEntityName()
												+ "' is not a dynamic entity" );
		}
		@SuppressWarnings("unchecked") //Safe, because we just checked
		final var dynamicEntity = (EntityDomainType<Map<String, ?>>) domainType;
		return new RootGraphImpl<>( null, dynamicEntity );
	}

	/**
	 * Merges multiple entity graphs into a single graph that specifies the
	 * fetching/loading of all attributes the input graphs specify.
	 *
	 * @param <T> Root entity type of the query and graph.
	 *
	 * @param entityManager {@code EntityManager} to use to create the new merged graph.
	 * @param root Root type of the entity for which the graph is being merged.
	 * @param graphs Graphs to merge.
	 *
	 * @return The merged graph.

View on GitHub (pinned to fad1729dce)

Solutions

  1. For POJO entities use EntityGraphs.createGraph(EntityType) or EntityManager.createEntityGraph(Class)
  2. If the entity is meant to be dynamic, map it with dynamic-map representation (entity-name, no class)
  3. Guard the call: check ((EntityDomainType<?>) type).getRepresentationMode() == RepresentationMode.MAP before invoking

Example fix

// before
EntityGraph<Map<String, ?>> graph =
        EntityGraphs.createGraphForDynamicEntity(metamodel.entity(Order.class)); // POJO → throws

// after
EntityGraph<Order> graph = EntityGraphs.createGraph(metamodel.entity(Order.class));
Defensive patterns

Strategy: type-guard

Type guard

static boolean isDynamicEntity(EntityType<?> entityType) {
    return entityType instanceof org.hibernate.metamodel.model.domain.EntityDomainType<?> domainType
            && domainType.getRepresentationMode() == RepresentationMode.MAP;
}

Prevention

When it happens

Trigger: Calling createGraphForDynamicEntity with a metamodel EntityType obtained for a normal @Entity class or a POJO hbm mapping; only entity-name/dynamic-map representations qualify.

Common situations: Domains that mix dynamic-map entities (legacy hbm entity-name mappings) with annotated POJOs; code copied from dynamic-entity examples; refactoring dynamic entities to POJO classes while keeping the graph helper.

Related errors


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