{"record":{"id":"96939d1715376e49","repo":"hibernate/hibernate-orm","slug":"cannot-unwrap-to-requested-type-96939d","errorCode":null,"errorMessage":"Cannot unwrap to requested type [{}]","messagePattern":"Cannot unwrap to requested type \\[(.+?)\\]","errorType":"exception","errorClass":"UnknownUnwrapTypeException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/AbstractMultiTenantConnectionProvider.java","lineNumber":66,"sourceCode":"\t\treturn getAnyConnectionProvider().supportsAggressiveRelease();\n\t}\n\n\t@Override\n\tpublic boolean isUnwrappableAs(@Nonnull Class<?> unwrapType) {\n\t\treturn unwrapType.isInstance( this )\n\t\t\t|| unwrapType.isAssignableFrom( ConnectionProvider.class );\n\t}\n\n\t@Override\n\tpublic <X> X unwrap(@Nonnull Class<X> unwrapType) {\n\t\tif ( unwrapType.isInstance( this ) ) {\n\t\t\treturn unwrapType.cast( this );\n\t\t}\n\t\telse if ( unwrapType.isAssignableFrom( ConnectionProvider.class ) ) {\n\t\t\treturn unwrapType.cast(  getAnyConnectionProvider() );\n\t\t}\n\t\telse {\n\t\t\tthrow new UnknownUnwrapTypeException( unwrapType );\n\t\t}\n\t}\n}\n","sourceCodeStart":48,"sourceCodeEnd":70,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/AbstractMultiTenantConnectionProvider.java#L48-L70","documentation":"Thrown by AbstractMultiTenantConnectionProvider.unwrap(Class) when the requested unwrap type is neither the provider instance itself (or a supertype of its concrete class) nor ConnectionProvider. Hibernate's multi-tenant connection providers only expose these two unwrap targets; anything else raises UnknownUnwrapTypeException. This is the standard JPA-style 'unwrap' contract, so frameworks commonly hit it when probing for concrete implementation types.","triggerScenarios":"Calling provider.unwrap(X.class) on an AbstractMultiTenantConnectionProvider subclass where X is not satisfied by type.isInstance(this) and X.isAssignableFrom(ConnectionProvider.class) is false - e.g. unwrap(DataSource.class), unwrap(DriverManagerConnectionProviderImpl.class) when the provider is DataSourceBasedMultiTenantConnectionProviderImpl, or unwrap to a pool-manager class (HikariDataSource, AgroalDataSource).","commonSituations":"Integration code (Spring, Quarkus, Micronaut, metrics/transaction managers) tries to unwrap the SessionFactory's connection provider to reach the underlying pool or DataSource. Custom MultiTenantConnectionProvider implementations that inherit the base unwrap behavior but are asked for tenant-specific types.","solutions":["Unwrap to ConnectionProvider.class instead, then use getAnyConnectionProvider() or getConnectionProvider(tenantId) to reach the concrete per-tenant provider","Unwrap to the concrete runtime class of the provider (or one of its supertypes that type.isInstance(provider) accepts)","If you own the provider class, override unwrap() in your AbstractMultiTenantConnectionProvider subclass to support additional target types","Get the DataSource another way (e.g. direct JNDI lookup) instead of unwrapping the connection provider"],"exampleFix":"// before\nDataSource ds = multiTenantProvider.unwrap(DataSource.class); // UnknownUnwrapTypeException\n\n// after\nConnectionProvider cp = multiTenantProvider.unwrap(ConnectionProvider.class);\nDataSource ds = cp.unwrap(DataSource.class); // delegate to the underlying per-tenant provider","handlingStrategy":"type-guard","validationCode":"// before unwrap: check the contract the base class enforces\nif ( !type.isInstance(provider) && !ConnectionProvider.class.isAssignableFrom(type) ) {\n    throw new IllegalArgumentException(\"Unsupported unwrap target: \" + type);\n}","typeGuard":"static boolean canUnwrap(MultiTenantConnectionProvider provider, Class<?> type) {\n    return type.isInstance(provider) || ConnectionProvider.class.isAssignableFrom(type);\n}","tryCatchPattern":"try {\n    return provider.unwrap(type);\n} catch (UnknownUnwrapTypeException e) {\n    // fall back to reaching the concrete provider explicitly\n    return type.cast(provider.getAnyConnectionProvider());\n}","preventionTips":["Never unwrap a multi-tenant provider to DataSource or pool types; unwrap to ConnectionProvider and follow getAnyConnectionProvider()/getConnectionProvider(tenantId) instead","If you control the provider, override unwrap() to advertise the concrete types you actually support"],"tags":["hibernate","multitenancy","unwrap","connection-provider","jdbc"],"backgroundTag":"unwrap-unsupported-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}