{"record":{"id":"70b4cd298e11ad55","repo":"hibernate/hibernate-orm","slug":"could-not-find-a-sessionfactory-uuid-name","errorCode":null,"errorMessage":"Could not find a SessionFactory [uuid={},name={}]","messagePattern":"Could not find a SessionFactory \\[uuid=(.+?),name=(.+?)\\]","errorType":"exception","errorClass":"InvalidObjectException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java","lineNumber":3675,"sourceCode":"\n\tprivate static SessionFactory locateSessionFactoryOnDeserialization(String uuid, String name) throws InvalidObjectException{\n\t\tfinal SessionFactory uuidResult = SessionFactoryRegistry.INSTANCE.getSessionFactory( uuid );\n\t\tif ( uuidResult != null ) {\n\t\t\tCORE_LOGGER.tracef( \"Resolved SessionFactory by UUID [%s]\", uuid );\n\t\t\treturn uuidResult;\n\t\t}\n\n\t\t// in case we were deserialized in a different JVM, look for an instance with the same name\n\t\t// (provided we were given a name)\n\t\tif ( name != null ) {\n\t\t\tfinal SessionFactory namedResult = SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( name );\n\t\t\tif ( namedResult != null ) {\n\t\t\t\tCORE_LOGGER.tracef( \"Resolved SessionFactory by name [%s]\", name );\n\t\t\t\treturn namedResult;\n\t\t\t}\n\t\t}\n\n\t\tthrow new InvalidObjectException( \"Could not find a SessionFactory [uuid=\" + uuid + \",name=\" + name + \"]\" );\n\t}\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// Non-standard HQL functions\n\n\t@Override\n\tpublic <T> SqmFunction<T> sql(String pattern, Class<T> type, Expression<?>... arguments) {\n\t\tfailIfSafeModeEnabled( safeModeEnabled, \"sql\", null );\n\t\tfinal List<SqmExpression<?>> sqmArguments = new ArrayList<>( expressionList( arguments ) );\n\t\tsqmArguments.add( 0, literal( pattern ) );\n\t\treturn getFunctionDescriptor( \"sql\" ).generateSqmExpression(\n\t\t\t\tsqmArguments,\n\t\t\t\tgetTypeConfiguration().standardBasicTypeForJavaType( type ),\n\t\t\t\tqueryEngine\n\t\t);\n\t}\n\n\t@Override","sourceCodeStart":3657,"sourceCodeEnd":3693,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java#L3657-L3693","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nStandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build();\nSessionFactory sf = new MetadataBuilderImpl... .buildSessionFactory(); // no name: only uuid resolvable in THIS jvm\nObject o = deserialize(bytesFromOtherNode); // InvalidObjectException\n\n// after\nStandardServiceRegistry ssr = new StandardServiceRegistryBuilder()\n        .applySetting(AvailableSettings.SESSION_FACTORY_NAME, \"main\")\n        .applySetting(AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, \"false\")\n        .build();\n// build + open the factory on the receiving node BEFORE deserialize(bytes);","handlingStrategy":"fallback","validationCode":"// On the receiving JVM, ensure a resolvable factory exists BEFORE deserializing\nif (SessionFactoryRegistry.INSTANCE.getNamedSessionFactory(\"main\") == null) {\n    throw new IllegalStateException(\"Build the named SessionFactory 'main' before deserializing criteria\");\n}","typeGuard":null,"tryCatchPattern":"try (ObjectInputStream in = new ObjectInputStream(bytes)) {\n    return in.readObject();\n} catch (InvalidObjectException e) {\n    // factory not registered here: rebuild it (by name) and retry, or reconstruct criteria from HQL\n    ensureSessionFactoryStarted();\n    return deserializeAgain(bytes);\n}","preventionTips":["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."],"tags":["hibernate","serialization","sessionfactory","distributed","deserialization"],"backgroundTag":"sessionfactory-deserialization-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}