hibernate/hibernate-orm · error · AssertionFailure
Tried to assemble a different subclass instance
Error message
Tried to assemble a different subclass instance
What it means
When Hibernate reassembles an entity from a second-level cache entry, StandardCacheEntryImpl.assemble verifies that the subclass name stored in the cache entry equals the entity name of the persister being loaded. A mismatch means the cache holds state written for a different class of the same inheritance hierarchy, breaking an internal invariant, so Hibernate throws AssertionFailure. In practice the cached entry is stale or was written by a different mapping version.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/cache/spi/entry/StandardCacheEntryImpl.java:135
* @param interceptor (currently unused)
* @param session The session
*
* @return The assembled state
*
* @throws HibernateException Indicates a problem performing assembly or calling the PreLoadEventListeners.
*
* @see org.hibernate.type.Type#assemble
* @see org.hibernate.type.Type#disassemble
*/
@Nonnull
public Object[] assemble(
@Nonnull final Object instance,
@Nonnull final Object id,
@Nonnull final EntityPersister persister,
@Nonnull final Interceptor interceptor,
@Nonnull final SharedSessionContractImplementor session) throws HibernateException {
if ( !persister.getEntityName().equals( subclass ) ) {
throw new AssertionFailure( "Tried to assemble a different subclass instance" );
}
// assembled state gets put in a new array (we read from cache by value!)
final Object[] state = CacheEntryHelper.assemble(
disassembledState,
persister.getPropertyTypes(),
session, instance
);
//persister.setIdentifier(instance, id); //before calling interceptor, for consistency with normal load
if ( session instanceof EventSource eventSource ) {
//TODO: reuse the PreLoadEvent
final PreLoadEvent preLoadEvent =
new PreLoadEvent( eventSource )
.setEntity( instance )
.setState( state )
.setId( id )View on GitHub (pinned to fad1729dce)
Solutions
- Clear the affected cache region (or the whole cache) after changing entity inheritance mappings
- Run identical mapping versions on all cluster nodes before they share cache regions
- Start with a fresh cache store after redeployment (wipe the disk store or restart the cache cluster)
- If it reproduces with consistent mappings and a clean cache, capture a minimal test case and report it to Hibernate (HHH)
Example fix
# before: redeploy with the old cache store in place # ./cache-store still holds entries from the previous mapping # after: evict on deploy sessionFactory.getCache().evictEntityRegions(); # or wipe the provider store before boot: rm -rf ./cache-store
Defensive patterns
Strategy: try-catch
Try / catch
try {
return session.find(Order.class, id);
} catch (AssertionFailure e) {
if (e.getMessage() != null && e.getMessage().contains("different subclass")) {
sessionFactory.getCache().evictEntityRegion(Order.class); // drop corrupt entry
return session.find(Order.class, id); // retry once from clean cache
}
throw e;
} Prevention
- Evict second-level cache regions on every deploy that changes entity mappings
- Version-stamp clustered caches and clear them during rolling upgrades
- Treat AssertionFailure during cache assembly as corrupt cache data, not a broad catch target
When it happens
Trigger: Loading an entity from the L2 cache after its inheritance hierarchy, subclass names, or entity names changed while the cache survived (Ehcache disk store, Infinispan cluster across restarts); cluster nodes running different application versions against the same region; migrated or manually seeded cache data.
Common situations: Redeploying with renamed subclasses or changed discriminator mappings without clearing the second-level cache; rolling upgrades where old and new nodes share a clustered cache; local testing against a leftover cache directory from a previous build.
Related errors
- Property '${property}' belongs to an entity subclass and may
- Entity '" + propertyHolder.getEntityName() + "' is a subclas
- Unable to locate entity table xref for entity [%s] super-typ
- proxy must be either an interface, or the class itself: {ent
- Root entity '<entityName>' is annotated '@DiscriminatorOptio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3da2afa3fe7de008.
Report an issue: GitHub.