{"record":{"id":"e0ae1b9e115114c1","repo":"hibernate/hibernate-orm","slug":"unable-to-locate-current-jta-transaction","errorCode":null,"errorMessage":"Unable to locate current JTA transaction","messagePattern":"Unable to locate current JTA transaction","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/context/internal/JTASessionContext.java","lineNumber":102,"sourceCode":"\t\ttry {\n\t\t\ttxn.registerSynchronization( buildCleanupSynch( txnIdentifier ) );\n\t\t}\n\t\tcatch ( Throwable t ) {\n\t\t\ttry {\n\t\t\t\tcurrentSession.close();\n\t\t\t}\n\t\t\tcatch ( Throwable e ) {\n\t\t\t\tCURRENT_SESSION_LOGGER.unableToReleaseGeneratedCurrentSessionOnFailedSynchronizationRegistration(e);\n\t\t\t}\n\t\t\tthrow new HibernateException( \"Unable to register cleanup Synchronization with TransactionManager\" );\n\t\t}\n\t}\n\n\tprivate static @Nonnull Transaction getTransaction(TransactionManager transactionManager) {\n\t\ttry {\n\t\t\tfinal var transaction = transactionManager.getTransaction();\n\t\t\tif ( transaction == null ) {\n\t\t\t\tthrow new HibernateException( \"Unable to locate current JTA transaction\" );\n\t\t\t}\n\t\t\tif ( !isActive( transaction.getStatus() ) ) {\n\t\t\t\t// We could register the session against the transaction even though it is\n\t\t\t\t// not started, but we'd have no guarantee of ever getting the map\n\t\t\t\t// entries cleaned up (aside from spawning threads).\n\t\t\t\tthrow new HibernateException( \"Current transaction is not in progress\" );\n\t\t\t}\n\t\t\treturn transaction;\n\t\t}\n\t\tcatch ( HibernateException e ) {\n\t\t\tthrow e;\n\t\t}\n\t\tcatch ( Throwable t ) {\n\t\t\tthrow new HibernateException( \"Problem locating/validating JTA transaction\", t );\n\t\t}\n\t}\n\n\t/**","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/context/internal/JTASessionContext.java#L84-L120","documentation":"JTASessionContext keys current sessions by JTA transaction. transactionManager.getTransaction() returned null, meaning no transaction is associated with the calling thread, so there is nothing to key or register a cleanup synchronization against, and Hibernate fails fast with this HibernateException.","triggerScenarios":"getCurrentSession() with JTA context before any transaction exists: before UserTransaction.begin() in SE, outside a CMT/@Transactional boundary, in @PostConstruct/servlet-filter code that runs before the transaction interceptor, or on a bare worker thread.","commonSituations":"Missing @Transactional on the entry method; interceptor/AOP ordering putting Hibernate access before the transaction interceptor; schedulers and executor tasks reusing getCurrentSession(); tests calling repositories without a wrapping transaction.","solutions":["Start the transaction before accessing the current session: UserTransaction.begin(), @Transactional (with proper propagation), or container-managed start","For non-transactional code paths use sessionFactory.openSession() in try-with-resources instead","Fix interceptor/filter ordering so the transaction boundary wraps the session access","In tests, make the test itself transactional (@Transactional test) or open sessions explicitly"],"exampleFix":"// before\nSession s = sessionFactory.getCurrentSession(); // no JTA tx on thread -> throws\n\n// after\nuserTransaction.begin();\ntry {\n    Session s = sessionFactory.getCurrentSession();\n    ...\n    userTransaction.commit();\n} catch (Exception e) {\n    userTransaction.rollback();\n}","handlingStrategy":"validation","validationCode":"TransactionManager tm = platform.retrieveTransactionManager();\nif (tm.getTransaction() == null) {\n    userTransaction.begin(); // ensure a transaction exists before asking for the current session\n}\nSession s = sessionFactory.getCurrentSession();","typeGuard":null,"tryCatchPattern":"try {\n    return sessionFactory.getCurrentSession();\n} catch (org.hibernate.HibernateException e) {\n    if (e.getMessage().contains(\"Unable to locate current JTA transaction\")) {\n        userTransaction.begin();\n        return sessionFactory.getCurrentSession(); // retry inside the newly begun transaction\n    }\n    throw e;\n}","preventionTips":["Mark entry points @Transactional so a transaction always exists before session access","Check interceptor ordering after adding new cross-cutting concerns","Use openSession() for genuinely non-transactional code paths"],"tags":["hibernate","jta","transaction","current-session","configuration"],"backgroundTag":"no-active-jta-transaction","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}