hibernate/hibernate-orm · error · InvalidObjectException
Could not find a SessionFactory [uuid={},name={}]
Error message
Could not find a SessionFactory [uuid={},name={}] What it means
SqmCriteriaNodeBuilder implements Serializable and resolves itself on deserialization via SessionFactoryRegistry, first by stored UUID then by factory name. If neither lookup finds a live SessionFactory in the current JVM, readResolve throws InvalidObjectException. This is by design: a node builder is meaningless without its factory's query engine, so deserialization must reattach to a registered factory.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java:3675
private static SessionFactory locateSessionFactoryOnDeserialization(String uuid, String name) throws InvalidObjectException{
final SessionFactory uuidResult = SessionFactoryRegistry.INSTANCE.getSessionFactory( uuid );
if ( uuidResult != null ) {
CORE_LOGGER.tracef( "Resolved SessionFactory by UUID [%s]", uuid );
return uuidResult;
}
// in case we were deserialized in a different JVM, look for an instance with the same name
// (provided we were given a name)
if ( name != null ) {
final SessionFactory namedResult = SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( name );
if ( namedResult != null ) {
CORE_LOGGER.tracef( "Resolved SessionFactory by name [%s]", name );
return namedResult;
}
}
throw new InvalidObjectException( "Could not find a SessionFactory [uuid=" + uuid + ",name=" + name + "]" );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Non-standard HQL functions
@Override
public <T> SqmFunction<T> sql(String pattern, Class<T> type, Expression<?>... arguments) {
failIfSafeModeEnabled( safeModeEnabled, "sql", null );
final List<SqmExpression<?>> sqmArguments = new ArrayList<>( expressionList( arguments ) );
sqmArguments.add( 0, literal( pattern ) );
return getFunctionDescriptor( "sql" ).generateSqmExpression(
sqmArguments,
getTypeConfiguration().standardBasicTypeForJavaType( type ),
queryEngine
);
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Give the SessionFactory a stable name before building it: cfg.setProperty(AvailableSettings.SESSION_FACTORY_NAME, "main") (and SESSION_FACTORY_NAME_IS_JNDI=false if you don't use JNDI) so other JVMs can resolve by name.
- Ensure the receiving JVM has fully built (and not yet closed) the SessionFactory before deserializing.
- Avoid serializing criteria trees at all: ship the HQL string or the TypedQueryReference and rebuild the criteria on the remote side.
Example fix
// before
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();
SessionFactory sf = new MetadataBuilderImpl... .buildSessionFactory(); // no name: only uuid resolvable in THIS jvm
Object o = deserialize(bytesFromOtherNode); // InvalidObjectException
// after
StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.applySetting(AvailableSettings.SESSION_FACTORY_NAME, "main")
.applySetting(AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, "false")
.build();
// build + open the factory on the receiving node BEFORE deserialize(bytes); Defensive patterns
Strategy: fallback
Validate before calling
// On the receiving JVM, ensure a resolvable factory exists BEFORE deserializing
if (SessionFactoryRegistry.INSTANCE.getNamedSessionFactory("main") == null) {
throw new IllegalStateException("Build the named SessionFactory 'main' before deserializing criteria");
} Try / catch
try (ObjectInputStream in = new ObjectInputStream(bytes)) {
return in.readObject();
} catch (InvalidObjectException e) {
// factory not registered here: rebuild it (by name) and retry, or reconstruct criteria from HQL
ensureSessionFactoryStarted();
return deserializeAgain(bytes);
} Prevention
- Always set a stable AvailableSettings.SESSION_FACTORY_NAME (and SESSION_FACTORY_NAME_IS_JNDI=false where JNDI is unused).
- Start the SessionFactory on the receiving node before any criteria deserialization.
- Prefer shipping HQL strings or TypedQueryReferences instead of serialized criteria trees.
When it happens
Trigger: Deserializing a criteria tree (or the builder itself) in a JVM/process where the SessionFactory that created it was closed, was never built, or was built without a name; sending serialized criteria over the wire (caches, messaging) to a node that has not started Hibernate; serializing into a session bean pool and deserializing after factory close.
Common situations: Distributed setups (Ignite/Coherence/JGroups) that replicate criteria objects; storing criteria queries in a serialized HTTP session and restoring after a restart where the factory name/uuid differs; unit tests that deserialize fixtures without booting a SessionFactory.
Related errors
- No SessionFactory with uuid [{uuid}] and name [{name}]
- could not deserialize
- Unable to deserialize from cached file [%s]
- Cannot serialize Session while connected
- Blobs may not be accessed after serialization
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/70b4cd298e11ad55.
Report an issue: GitHub.