{"record":{"id":"2d2ba37a808b72a9","repo":"hibernate/hibernate-orm","slug":"unsupported-attempt-to-wrap-map-entry-value","errorCode":null,"errorMessage":"Unsupported attempt to wrap Map.Entry value","messagePattern":"Unsupported attempt to wrap Map\\.Entry value","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/MapEntryJavaType.java","lineNumber":41,"sourceCode":"\tpublic static final MapEntryJavaType INSTANCE = new MapEntryJavaType();\n\n\tpublic MapEntryJavaType() {\n\t\tsuper( Map.Entry.class );\n\t}\n\n\t@Override\n\tpublic JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {\n\t\tthrow new UnsupportedOperationException( \"Unsupported attempt to resolve JDBC type for Map.Entry\" );\n\t}\n\n\t@Override\n\tpublic <X> X unwrap(Map.Entry value, Class<X> type, WrapperOptions options) {\n\t\tthrow new UnsupportedOperationException( \"Unsupported attempt to unwrap Map.Entry value\" );\n\t}\n\n\t@Override\n\tpublic <X> Map.Entry wrap(X value, WrapperOptions options) {\n\t\tthrow new UnsupportedOperationException( \"Unsupported attempt to wrap Map.Entry value\" );\n\t}\n}\n","sourceCodeStart":23,"sourceCodeEnd":44,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/MapEntryJavaType.java#L23-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","Never declare Map.Entry as a mapped attribute type; model maps with @ElementCollection or @OneToMany so Hibernate maps key and value columns separately."],"exampleFix":"// before\nList<Map.Entry<String,Integer>> rows = session\n    .createQuery(\"select e from MyEntity e join e.scores m where m = :p\", Map.Entry.class)\n    .setParameter(\"p\", Map.entry(\"a\", 1))\n    .getResultList(); // wrap(Map.Entry) -> UnsupportedOperationException\n\n// after\nList<Object[]> rows = session\n    .createQuery(\"select key(s), value(s) from MyEntity e join e.scores s\", Object[].class)\n    .getResultList();","handlingStrategy":"validation","validationCode":"// Before executing, make sure no parameter uses Map.Entry as its type\nfor (jakarta.persistence.Parameter<?> p : query.getParameters()) {\n    if (Map.Entry.class.isAssignableFrom(p.getParameterType())) {\n        throw new IllegalArgumentException(\n            \"Map.Entry cannot be bound directly; use key()/value(): \" + p.getName());\n    }\n}","typeGuard":"static boolean isBindableJavaType(Class<?> javaType) {\n    return !Map.Entry.class.isAssignableFrom(javaType);\n}","tryCatchPattern":"try {\n    query.getResultList();\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Map.Entry\")) {\n        // rewrite the query with key(m)/value(m) instead of the entry/map alias\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use KEY(m)/VALUE(m) in HQL over map joins instead of referencing the map alias","Never declare Map.Entry as an attribute type or converter target","Review custom UserTypes so they never route Map.Entry through JavaTypeRegistry"],"tags":["hibernate","orm","hql","map-entry","java-type-descriptor","unsupported-operation"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}