hibernate/hibernate-orm · error · SessionException
Cannot redefine the tenant identifier on a child session if
Error message
Cannot redefine the tenant identifier on a child session if the connection is reused
What it means
Stateless-session variant of the tenant guard in SharedStatelessSessionBuilderImpl.open(): when the derived stateless session shares the original's transaction coordinator under multi-tenancy, Hibernate compares the builder's tenant identifier with the original session's and throws if they differ. A shared connection is already associated with the original tenant, so a different tenant identifier would violate isolation.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/creation/internal/SharedStatelessSessionBuilderImpl.java:61
@Override
protected SharedStatelessSessionBuilder getThis() {
return this;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SharedStatelessSessionBuilder
@Override
@Nonnull
public StatelessSessionImplementor open() {
CORE_LOGGER.openingStatelessSession( options.getTenantIdentifierValue() );
if ( original.getSessionFactory().getSessionFactoryOptions().isMultiTenancyEnabled() ) {
if ( options.isTransactionCoordinatorShared() ) {
final var tenantId = original.getTenantIdentifierValue();
assert tenantId != null;
if ( !Objects.equals( tenantId, options.getTenantIdentifierValue() ) ) {
throw new SessionException( "Cannot redefine the tenant identifier on a child session if the connection is reused" );
}
}
}
return createStatelessSession( options );
}
@Override
@Nonnull
public StatelessSession openStatelessSession() {
return open();
}
@Override
@Nonnull
public SharedStatelessSessionBuilder connection() {
options.shareTransactionContext();
return this;
}View on GitHub (pinned to fad1729dce)
Solutions
- Drop the .tenantIdentifier(...) call if the child should keep the original tenant.
- Open an independent stateless session from the factory with the target tenant: factory.openStatelessSession(tenantId).
- Do not share the transaction coordinator if the child must run under another tenant.
- Assert in code that derived stateless sessions always pass the same tenant id as the parent.
Example fix
// before - shared connection, different tenant -> SessionException
StatelessSession child = parentStateless.sessionWithOptions()
.transaction()
.tenantIdentifier("tenant-b")
.openStatelessSession();
// after - separate stateless session per tenant
StatelessSession child = sessionFactory.openStatelessSession(tenantBIdentifier); Defensive patterns
Strategy: validation
Validate before calling
// For shared stateless child sessions, pass the parent's tenant identifier only
Object parentTenant = parentStateless.getTenantIdentifierValue();
StatelessSessionBuilder b = parentStateless.sessionWithOptions().transaction();
if (targetTenant != null && !Objects.equals(targetTenant, parentTenant)) {
return factory.openStatelessSession(targetTenant); // separate connection
}
return b.openStatelessSession(); Try / catch
catch (SessionException e) {
if (e.getMessage() != null && e.getMessage().contains("tenant identifier on a child session")) {
return factory.openStatelessSession(targetTenantId);
}
throw e;
} Prevention
- Derive shared stateless sessions only within the same tenant scope.
- Add an assertion in batch-job bootstrap: child tenant id equals parent tenant id.
- Open stateless sessions per tenant from the factory in multi-tenant batch pipelines.
When it happens
Trigger: statelessSession.sessionWithOptions()...openStatelessSession() (or .open()) with transaction/connection sharing and multi-tenancy enabled, where .tenantIdentifier(...) was called with a value not equal to the original session's tenant (the builder throws on any non-equal value, since the original tenant is asserted non-null).
Common situations: Batch import/export jobs deriving stateless sessions from a tenant session but targeting another tenant; refactor where the tenant id parameter stopped matching the session's tenant; multi-tenant bulk processing pipelines.
Related errors
- Cannot redefine the tenant identifier on a child session if
- Cannot redefine the read-only mode on a child session if the
- MySQL does not support dropping creating/dropping schemas in
- all @TenantId fields must have the same type: <parameterType
- @TenantId attribute must be mapped to a single column or for
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a25c7977e36a4abc.
Report an issue: GitHub.