{"record":{"id":"4e1157012640e4e4","repo":"hibernate/hibernate-orm","slug":"ddltransactionisolatorjtaimpl-could-not-locate-tra","errorCode":null,"errorMessage":"DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; base JtaPlatform impl (${jtaPlatform})?","messagePattern":"DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; base JtaPlatform impl \\((.+?)\\)\\?","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java","lineNumber":42,"sourceCode":" */\npublic class DdlTransactionIsolatorJtaImpl implements DdlTransactionIsolator {\n\tprivate final JdbcContext jdbcContext;\n\n\tprivate final Transaction suspendedTransaction;\n\tprivate Connection jdbcConnection;\n\n\tprivate static JtaPlatform getJtaPlatform(JdbcContext jdbcContext) {\n\t\treturn jdbcContext.getServiceRegistry().requireService( JtaPlatform.class );\n\t}\n\n\tpublic DdlTransactionIsolatorJtaImpl(JdbcContext jdbcContext) {\n\t\tthis.jdbcContext = jdbcContext;\n\n\t\ttry {\n\t\t\tfinal var jtaPlatform = getJtaPlatform( jdbcContext );\n\t\t\tfinal var transactionManager = jtaPlatform.retrieveTransactionManager();\n\t\t\tif ( transactionManager == null ) {\n\t\t\t\tthrow new HibernateException(\n\t\t\t\t\t\t\"DdlTransactionIsolatorJtaImpl could not locate TransactionManager to suspend any current transaction; \" +\n\t\t\t\t\t\t\"base JtaPlatform impl (\" + jtaPlatform + \")?\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tsuspendedTransaction = transactionManager.suspend();\n\t\t\tJTA_LOGGER.suspendedTransactionForDdlIsolation( suspendedTransaction );\n\t\t}\n\t\tcatch (SystemException e) {\n\t\t\tthrow new HibernateException( \"Unable to suspend current JTA transaction in preparation for DDL execution\" );\n\t\t}\n\n\t}\n\n\t@Override\n\tpublic JdbcContext getJdbcContext() {\n\t\treturn jdbcContext;\n\t}\n","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java#L24-L60","documentation":"HibernateException from DdlTransactionIsolatorJtaImpl: to run DDL isolated from the current JTA transaction Hibernate must suspend that transaction, but the configured JtaPlatform's retrieveTransactionManager() returned null — there is no TransactionManager to suspend with. The JtaPlatform in effect is wrong or is a stub that cannot supply a TM (the message even names the impl found).","triggerScenarios":"Running schema tools (hibernate.hbm2ddl.auto=update/create, SchemaExport/SchemaUpdate) in a JTA-configured runtime where hibernate.transaction.jta.platform resolves to an implementation without a TransactionManager — e.g. a bare JtaPlatformBaseImpl subclass, a testing stub that only implements retrieveUserTransaction(), or an app-server platform used outside its server so its JNDI lookup returns null.","commonSituations":"Hand-rolled JtaPlatform classes in Spring Boot + embedded JTA (Atomikos/Narayana) setups; standalone apps hard-coding the platform class; migrations to a new app server whose JNDI names differ so the TM lookup silently fails.","solutions":["Configure a JtaPlatform that actually exposes the TransactionManager for your runtime (e.g. JBossAppServerJtaPlatform on WildFly, or a Narayana/Atomikos-aware implementation for embedded use)","If you implement JtaPlatform yourself, return a real TransactionManager from retrieveTransactionManager()","Move DDL out of the JTA boot path: run Flyway/Liquibase before Hibernate starts and set hbm2ddl.auto to validate or none","As a stopgap, run the schema-update phase with a resource-local configuration"],"exampleFix":"// before\nprops.put(\"hibernate.transaction.jta.platform\", MyStubJtaPlatform.class.getName()); // retrieveTransactionManager() == null\nprops.put(\"hibernate.hbm2ddl.auto\", \"update\");\n\n// after\nprops.put(\"hibernate.transaction.jta.platform\",\n    \"org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform\");\n// or: run migrations with Flyway before boot, then hbm2ddl.auto=validate","handlingStrategy":"validation","validationCode":"// before running schema tools in a JTA runtime, sanity-check the platform exposes a TM\nTransactionManager tm = jtaPlatform.retrieveTransactionManager();\nif (tm == null) {\n  throw new IllegalStateException(\"JtaPlatform (\" + jtaPlatform + \") exposes no TransactionManager; fix jta.platform config before DDL\");\n}","typeGuard":null,"tryCatchPattern":"catch (org.hibernate.HibernateException e) {\n  // named the useless JtaPlatform in its message: replace it with a runtime-correct\n  // implementation (or externalize DDL to Flyway/Liquibase) instead of retrying\n}","preventionTips":["Use the JtaPlatform matching your runtime rather than custom stubs","Run schema migrations before the JTA runtime boots","Smoke-test retrieveTransactionManager() != null in startup checks"],"tags":["hibernate","jta","ddl","transaction-manager","bootstrap"],"backgroundTag":"jta-transaction-manager-not-found","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}