{"record":{"id":"40b0768efc784c9a","repo":"hibernate/hibernate-orm","slug":"unwrap-strategy-not-known-for-this-java-type-40b076","errorCode":null,"errorMessage":"Unwrap strategy not known for this Java type: \" + getTypeName()","messagePattern":"Unwrap strategy not known for this Java type: \" \\+ getTypeName\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeBasicAdaptor.java","lineNumber":42,"sourceCode":"\tpublic JavaTypeBasicAdaptor(Class<T> type, MutabilityPlan<T> mutabilityPlan) {\n\t\tsuper( type, mutabilityPlan );\n\t}\n\n\t@Override\n\tpublic JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {\n\t\tthrow new JdbcTypeRecommendationException(\n\t\t\t\t\"Could not determine recommended JdbcType for '\" + getTypeName() + \"'\"\n\t\t);\n\t}\n\n\t@Override\n\tpublic boolean useObjectEqualsHashCode() {\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic <X> X unwrap(T value, Class<X> type, WrapperOptions options) {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\t\"Unwrap strategy not known for this Java type: \" + getTypeName()\n\t\t);\n\t}\n\n\t@Override\n\tpublic <X> T wrap(X value, WrapperOptions options) {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\t\"Wrap strategy not known for this Java type: \" + getTypeName()\n\t\t);\n\t}\n\n\t@Override\n\tpublic String toString() {\n\t\treturn \"JavaTypeBasicAdaptor(\" + getTypeName() + \")\";\n\t}\n}\n","sourceCodeStart":24,"sourceCodeEnd":59,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeBasicAdaptor.java#L24-L59","documentation":"The adaptor's unwrap() is intentionally unimplemented — a bare JavaType has no conversion semantics. Any code path reaching unwrap() on a JavaTypeBasicAdaptor (custom binders, converters, session operations) gets UnsupportedOperationException, signalling the mapping never supplied a JdbcType or converter to do the real work.","triggerScenarios":"Binding or reading an attribute whose JavaType is only a registered adaptor, with no JdbcType/converter performing conversion; generic framework code calling unwrap() on arbitrary descriptors it discovers.","commonSituations":"Registrations that only flag a class as 'basic' without behavior; scaffolding types left in production mappings; integration code probing descriptors generically.","solutions":["Give the mapping a real JdbcType or AttributeConverter so unwrap() is never called on the adaptor","Subclass AbstractClassJavaType and implement unwrap()/wrap() with real conversion","Replace the bare registration with a full BasicType implementation"],"exampleFix":"// before\npublic class MoneyJavaType extends JavaTypeBasicAdaptor<Money> {\n    public MoneyJavaType() { super(Money.class); }\n    // unwrap inherited -> always throws\n}\n\n// after\npublic class MoneyJavaType extends AbstractClassJavaType<Money> {\n    public MoneyJavaType() { super(Money.class); }\n    @Override public <X> X unwrap(Money v, Class<X> t, WrapperOptions o) {\n        if (t == String.class) return (X) v.toString();\n        if (t == BigDecimal.class) return (X) v.amount();\n        throw unknownUnwrap(t);\n    }\n}","handlingStrategy":"type-guard","validationCode":"static boolean hasRealUnwrap(JavaType<?> jt) {\n    return !(jt instanceof org.hibernate.type.descriptor.java.spi.JavaTypeBasicAdaptor);\n}\n// skip generic unwrap paths for adaptor-backed descriptors","typeGuard":"static boolean unwrapSafe(JavaType<?> javaType) {\n    return !(javaType instanceof org.hibernate.type.descriptor.java.spi.JavaTypeBasicAdaptor);\n}","tryCatchPattern":"try {\n    X v = javaType.unwrap(value, target, options);\n} catch (UnsupportedOperationException e) {\n    // adaptor cannot convert: perform the conversion manually or fix the registration\n    throw new IllegalStateException(\"type registration incomplete for \"\n        + javaType.getJavaTypeClass(), e);\n}","preventionTips":["Never rely on adaptor descriptors for value conversion — implement unwrap/wrap","Audit custom JavaTypes for inherited throwing methods","Test one read + one write per custom type in CI"],"tags":["hibernate","orm","unwrap","custom-type"],"backgroundTag":"unsupported-type-conversion","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}