{"record":{"id":"1af03ee8eaa90b8f","repo":"hibernate/hibernate-orm","slug":"unknown-unwrap-conversion-requested-type-gett","errorCode":null,"errorMessage":"Unknown unwrap conversion requested: \" + type.getTypeName() + \" to \" + conversionType.getName()","messagePattern":"Unknown unwrap conversion requested: \" \\+ type\\.getTypeName\\(\\) \\+ \" to \" \\+ conversionType\\.getName\\(\\)","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractJavaType.java","lineNumber":88,"sourceCode":"\t}\n\n\t@Override\n\tpublic boolean areEqual(T one, T another) {\n\t\treturn Objects.equals( one, another );\n\t}\n\n\t@Override\n\tpublic Comparator<T> getComparator() {\n\t\treturn comparator;\n\t}\n\n\t@Override\n\tpublic String extractLoggableRepresentation(T value) {\n\t\treturn (value == null) ? \"null\" : value.toString();\n\t}\n\n\tprotected HibernateException unknownUnwrap(Class<?> conversionType) {\n\t\tthrow new HibernateException(\n\t\t\t\t\"Unknown unwrap conversion requested: \" + type.getTypeName() + \" to \" + conversionType.getName()\n\t\t);\n\t}\n\n\tprotected HibernateException unknownWrap(Class<?> conversionType) {\n\t\tthrow new HibernateException(\n\t\t\t\t\"Unknown wrap conversion requested: \" + conversionType.getName() + \" to \" + type.getTypeName()\n\t\t);\n\t}\n}\n","sourceCodeStart":70,"sourceCodeEnd":99,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractJavaType.java#L70-L99","documentation":"AbstractJavaType.unknownUnwrap is the fallback used by JavaType.unwrap(value, conversionType, options) when a descriptor does not support unwrapping its values to the requested Java class. It signals that a value must be converted to a type for which no conversion path is defined on that descriptor.","triggerScenarios":"Binding or reading a value through a JavaType whose unwrap() only supports specific targets: e.g. a custom JavaType that handles String/Integer but receives a request to unwrap to java.sql.Date, or passing a value of the wrong type to setParameter so Hibernate tries to unwrap the value's descriptor to the parameter's JDBC-expect­ed Java type.","commonSituations":"Custom JavaType implementations that override unwrap() without covering all needed target types; passing a LocalDate to a parameter mapped as String (or similar mismatches); result extraction where the driver returns a type the descriptor cannot unwrap; upgrading Hibernate versions where additional unwrap paths started being requested.","solutions":["Pass values of the attribute's declared type (or types its JavaType explicitly supports)","Extend the custom JavaType's unwrap() to handle the requested conversionType","Prefer an AttributeConverter for domain<->relational conversion instead of ad-hoc unwrap calls","If the mismatch is on a query parameter, bind with an explicit type: setParameter(name, value, type)"],"exampleFix":"// before\npublic class MoneyJavaType extends AbstractClassJavaType<Money> {\n    @Override\n    public <X> X unwrap(Money value, Class<X> type, WrapperOptions options) {\n        if (type == String.class) return (X) value.asString();\n        return unknownUnwrap(type); // fails for BigDecimal\n    }\n}\n// after\n@Override\npublic <X> X unwrap(Money value, Class<X> type, WrapperOptions options) {\n    if (type == String.class) return (X) value.asString();\n    if (type == BigDecimal.class) return (X) value.amount();\n    return unknownUnwrap(type);\n}","handlingStrategy":"type-guard","validationCode":"// before passing a foreign value to a typed parameter, check convertibility\nObject v = /* candidate */;\nClass<?> expected = String.class; // parameter's Java type\nif (!expected.isInstance(v) && !(v instanceof Number) && !(v instanceof java.util.Date)) {\n    v = String.valueOf(v); // explicit conversion instead of relying on unwrap\n}","typeGuard":"// in a custom JavaType: enumerate supported targets and check before unwrap\nprivate static final Set<Class<?>> SUPPORTED = Set.of(String.class, Integer.class, BigDecimal.class);\n\n@SuppressWarnings(\"unchecked\")\nstatic <X> boolean canUnwrap(Class<X> type) { return SUPPORTED.contains(type); }","tryCatchPattern":"try {\n    query.setParameter(\"code\", value);\n} catch (HibernateException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Unknown unwrap conversion requested\")) {\n        query.setParameter(\"code\", convertToExpectedType(value)); // retry once with the right type\n    } else throw e;\n}","preventionTips":["Always bind values of the attribute's declared type","Cover String, toString-able and JDBC types in custom unwrap() implementations","Keep an integration test per custom JavaType exercising bind + read","Use AttributeConverter for domain conversions rather than ad-hoc unwrap reliance"],"tags":["hibernate","orm","type-conversion","unwrap","custom-type","query-parameters"],"backgroundTag":"unsupported-java-type-conversion","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}