{"record":{"id":"0121d6072f975c52","repo":"hibernate/hibernate-orm","slug":"unable-to-perform-isolated-work","errorCode":null,"errorMessage":"Unable to perform isolated work","messagePattern":"Unable to perform isolated work","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaIsolationDelegate.java","lineNumber":119,"sourceCode":"\t\ttry {\n\t\t\t// suspend current JTA transaction, if any\n\t\t\tsurroundingTransaction = suspend();\n\t\t}\n\t\tcatch ( SystemException systemException ) {\n\t\t\tthrow new TransactionException( \"Unable to suspend current JTA transaction\", systemException );\n\t\t}\n\n\t\tThrowable exception = null;\n\t\ttry {\n\t\t\treturn callable.call();\n\t\t}\n\t\tcatch ( HibernateException he ) {\n\t\t\texception = he;\n\t\t\tthrow he;\n\t\t}\n\t\tcatch ( Throwable throwable ) {\n\t\t\texception = throwable;\n\t\t\tthrow new HibernateException( \"Unable to perform isolated work\", throwable );\n\t\t}\n\t\tfinally {\n\t\t\ttry {\n\t\t\t\t// resume the JTA transaction we suspended\n\t\t\t\tresume( surroundingTransaction );\n\t\t\t}\n\t\t\tcatch ( Throwable throwable ) {\n\t\t\t\t// if the actual work had an error, use that; otherwise throw this error\n\t\t\t\tif ( exception == null ) {\n\t\t\t\t\tthrow new TransactionException( \"Unable to resume suspended transaction\", throwable );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\texception.addSuppressed( throwable );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaIsolationDelegate.java#L101-L137","documentation":"HibernateException from JtaIsolationDelegate: the isolated work itself (run inside a suspended-transaction window under JTA) threw a non-Hibernate Throwable, which is wrapped with this message; HibernateExceptions rethrow unchanged. The cause holds the real failure — typically a SQLException from the isolated statement or a defect in custom Work code.","triggerScenarios":"Isolated work under JTA fails: a table-based ID generator's isolated SELECT/UPDATE hitting a missing table or missing privileges, a missing sequence during information extraction, SQL errors in custom Work executed via the delegate, or an NPE inside the work.","commonSituations":"Schema created without the generator table/sequence under a JTA deployment; renamed schema objects after migration; read-restricted DB users lacking grants on generator tables; first persist after deployment surfacing the missing object.","solutions":["Unwrap and inspect the cause — it is the actual exception (SQL error, missing table, NPE) with the failing statement","Create or grant the schema object the isolated work touches (generator table/sequence) and keep migrations in sync with @TableGenerator/@SequenceGenerator mappings","Run hibernate.hbm2ddl.auto=validate at startup to catch missing objects before the first insert","For custom Work implementations, fix the defect the cause points to"],"exampleFix":"// before\n@TableGenerator(name = \"ids\", table = \"id_gen\")\n// id_gen missing in the JTA-managed schema -> 'Unable to perform isolated work' on first persist\n\n// after\n// migration: CREATE TABLE id_gen (k VARCHAR(64) PRIMARY KEY, v BIGINT NOT NULL);\n//            INSERT INTO id_gen (k, v) VALUES ('ids', 0);\n// plus: hibernate.hbm2ddl.auto=validate to fail at startup instead of first insert","handlingStrategy":"try-catch","validationCode":"// fail fast at startup: verify generator objects exist before the first insert\nSession s = sessionFactory.openSession();\ns.doWork(conn -> {\n  try (var rs = conn.createStatement()\n          .executeQuery(\"select 1 from id_gen where k = 'ids'\")) { // generator table probe\n    if (!rs.next()) throw new IllegalStateException(\"ID generator table not initialized\");\n  }\n});","typeGuard":"static SQLException findSqlException(Throwable t) {\n  for (Throwable c = t; c != null; c = c.getCause()) {\n    if (c instanceof SQLException s) return s;\n  }\n  return null;\n}","tryCatchPattern":"try {\n  em.persist(entity);\n  em.flush();\n} catch (org.hibernate.HibernateException e) {\n  // 'Unable to perform isolated work': unwrap the cause — it carries the real SQL/defect;\n  // fix the schema object or the Work implementation, then retry in a new transaction\n}","preventionTips":["Run hibernate.hbm2ddl.auto=validate at startup to catch missing generator objects","Keep DDL migrations synchronized with generator mappings","Grant the app DB user privileges on generator tables/sequences"],"tags":["hibernate","jta","id-generation","jdbc","isolated-work"],"backgroundTag":"jdbc-sql-execution-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}