hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported attempt to wrap Map.Entry value

Error message

Unsupported attempt to wrap Map.Entry value

What it means

MapEntryJavaType is a synthetic JavaType descriptor Hibernate uses to model a Map entry (key+value pair) as a single unit while mapping Map attributes. It has no JDBC representation: getRecommendedJdbcType(), unwrap() and wrap() deliberately throw UnsupportedOperationException because converting a Map.Entry to or from a JDBC value is meaningless. Seeing 'Unsupported attempt to wrap Map.Entry value' means application code or a query treated the map entry itself as one bindable value.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/MapEntryJavaType.java:41

	public static final MapEntryJavaType INSTANCE = new MapEntryJavaType();

	public MapEntryJavaType() {
		super( Map.Entry.class );
	}

	@Override
	public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
		throw new UnsupportedOperationException( "Unsupported attempt to resolve JDBC type for Map.Entry" );
	}

	@Override
	public <X> X unwrap(Map.Entry value, Class<X> type, WrapperOptions options) {
		throw new UnsupportedOperationException( "Unsupported attempt to unwrap Map.Entry value" );
	}

	@Override
	public <X> Map.Entry wrap(X value, WrapperOptions options) {
		throw new UnsupportedOperationException( "Unsupported attempt to wrap Map.Entry value" );
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rewrite the HQL/Criteria to target the map parts explicitly: use KEY(m) and VALUE(m) instead of the map alias or a Map.Entry parameter.
  2. If you need key+value together, select a projection: 'select key(m), value(m) from Entity e join e.map m' and assemble entries client-side.
  3. Never declare Map.Entry as a mapped attribute type; model maps with @ElementCollection or @OneToMany so Hibernate maps key and value columns separately.

Example fix

// before
List<Map.Entry<String,Integer>> rows = session
    .createQuery("select e from MyEntity e join e.scores m where m = :p", Map.Entry.class)
    .setParameter("p", Map.entry("a", 1))
    .getResultList(); // wrap(Map.Entry) -> UnsupportedOperationException

// after
List<Object[]> rows = session
    .createQuery("select key(s), value(s) from MyEntity e join e.scores s", Object[].class)
    .getResultList();
Defensive patterns

Strategy: validation

Validate before calling

// Before executing, make sure no parameter uses Map.Entry as its type
for (jakarta.persistence.Parameter<?> p : query.getParameters()) {
    if (Map.Entry.class.isAssignableFrom(p.getParameterType())) {
        throw new IllegalArgumentException(
            "Map.Entry cannot be bound directly; use key()/value(): " + p.getName());
    }
}

Type guard

static boolean isBindableJavaType(Class<?> javaType) {
    return !Map.Entry.class.isAssignableFrom(javaType);
}

Try / catch

try {
    query.getResultList();
} catch (UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().contains("Map.Entry")) {
        // rewrite the query with key(m)/value(m) instead of the entry/map alias
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Binding or comparing a whole Map.Entry as a query parameter (HQL over a map join alias: 'where m = :entry'); selecting the map itself in a context that routes entries through the type system; declaring Map.Entry as an entity attribute type; a custom converter/UserType whose Java type resolves to Map.Entry and is then wrapped during flush.

Common situations: Querying @ElementCollection Map attributes and referencing the map alias directly instead of KEY(m)/VALUE(m); tuple comparisons on map joins; custom types built around Map.Entry; behavior changes after Hibernate 6.x upgrades of map-entry result mapping.

Related errors


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