{"record":{"id":"853589a237044994","repo":"hibernate/hibernate-orm","slug":"unable-to-unwrap-to","errorCode":null,"errorMessage":"Unable to unwrap to {}","messagePattern":"Unable to unwrap to (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java","lineNumber":918,"sourceCode":"\t@Override\n\tpublic SqmPredicate wrap(List<? extends Expression<Boolean>> restrictions) {\n\t\tif ( restrictions.size() == 1 ) {\n\t\t\treturn wrap( restrictions.get( 0 ) );\n\t\t}\n\t\telse {\n\t\t\tfinal List<SqmPredicate> predicates = new ArrayList<>( restrictions.size() );\n\t\t\tfor ( var expression : restrictions ) {\n\t\t\t\tpredicates.add( wrap( expression ) );\n\t\t\t}\n\t\t\treturn new SqmJunctionPredicate( Predicate.BooleanOperator.AND, predicates, this );\n\t\t}\n\t}\n\n\t@Override @SuppressWarnings(\"unchecked\")\n\tpublic <T extends HibernateCriteriaBuilder> T unwrap(Class<T> clazz) {\n\t\tfinal T result = (T) extensions.get( clazz );\n\t\tif ( result == null ) {\n\t\t\tthrow new IllegalArgumentException( \"Unable to unwrap to \" + clazz.getName() );\n\t\t}\n\t\treturn result;\n\t}\n\n\t@Override\n\tpublic SqmPath<?> fk(Path<?> path) {\n\t\tfinal var sqmPath = (SqmPath<?>) path;\n\t\tfinal var toOneReference = sqmPath.getReferencedPathSource();\n\t\tfinal boolean validToOneRef =\n\t\t\t\ttoOneReference.getBindableType() == Bindable.BindableType.SINGULAR_ATTRIBUTE\n\t\t\t\t\t\t&& toOneReference instanceof EntitySqmPathSource;\n\t\tif ( !validToOneRef ) {\n\t\t\tthrow new FunctionArgumentException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Argument '%s' of 'fk()' function is not a single-valued association\",\n\t\t\t\t\t\t\tsqmPath.getNavigablePath()\n\t\t\t\t\t)","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java#L900-L936","documentation":"SqmCriteriaNodeBuilder.unwrap(Class) only resolves classes registered in its internal 'extensions' map; it is not a general JPA-style unwrap that adapts to arbitrary target types. Asking for any class not present in that registry throws IllegalArgumentException with the requested class name. In practice the map contains the node builder's own registered extensions (first and foremost SqmCriteriaNodeBuilder/HibernateCriteriaBuilder itself).","triggerScenarios":"criteriaBuilder.unwrap(Session.class), unwrap(SessionFactory.class), unwrap(MyCustomBuilder.class), or any jakarta.persistence interface other than a registered criteria-builder extension.","commonSituations":"Generic framework code that defensively calls unwrap(SomeApi.class) on every JPA object (works on EntityManager, fails here); migrating code from EclipseLink/OpenJPA where unwrap is more permissive; attempting to reach the Session from the CriteriaBuilder.","solutions":["Remove the unwrap call: the object you get from session.getCriteriaBuilder() already IS the HibernateCriteriaBuilder — assign it directly (HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder) session.getCriteriaBuilder()).","To reach the Session/SessionFactory, unwrap the EntityManager/Session instead of the CriteriaBuilder (em.unwrap(Session.class)).","If you truly need a specific extension, unwrap only to the documented target: cb.unwrap(HibernateCriteriaBuilder.class) or SqmCriteriaNodeBuilder.class."],"exampleFix":"// before\nSession s = criteriaBuilder.unwrap(Session.class); // Unable to unwrap to org.hibernate.Session\n\n// after\nSession s = em.unwrap(Session.class);\nHibernateCriteriaBuilder hcb = (HibernateCriteriaBuilder) criteriaBuilder;","handlingStrategy":"type-guard","validationCode":"// unwrap() only resolves registered criteria-builder extensions; probe the known ones\nObject ext = null;\nfor (Class<?> c : List.of(HibernateCriteriaBuilder.class, SqmCriteriaNodeBuilder.class)) {\n    try { ext = criteriaBuilder.unwrap(c); break; } catch (IllegalArgumentException ignored) { }\n}","typeGuard":"static boolean isUnwrappableCriteriaExtension(CriteriaBuilder cb, Class<?> target) {\n    return target == HibernateCriteriaBuilder.class\n        || target == SqmCriteriaNodeBuilder.class; // registered extension types","tryCatchPattern":"try {\n    HibernateCriteriaBuilder hcb = criteriaBuilder.unwrap(HibernateCriteriaBuilder.class);\n} catch (IllegalArgumentException e) {\n    // not a registered extension: cast directly instead (the object already implements it)\n    HibernateCriteriaBuilder hcb = (HibernateCriteriaBuilder) criteriaBuilder;\n}","preventionTips":["Never unwrap the CriteriaBuilder to reach the Session/EntityManagerFactory; unwrap the EntityManager instead.","Prefer direct casting: what you get from session.getCriteriaBuilder() already implements HibernateCriteriaBuilder.","Reserve unwrap() calls for APIs that document the supported targets."],"tags":["hibernate","criteria","unwrap","jpa"],"backgroundTag":"unwrap-unsupported-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}