Skip to content

JtaTransactionManager created with the JtaTransactionManagerFactoryBean is not ready to use #22605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bbodnar opened this issue Mar 16, 2019 · 9 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Milestone

Comments

@bbodnar
Copy link

bbodnar commented Mar 16, 2019

A JtaTransactionManager created with the JtaTransactionManagerFactoryBean (the only way to get the proper JTA-support when using a Java-configuration, introduced in [SPR-12197]) is not ready to use, because JtaTransactionManager is an InitializingBean and InitializingBean.afterPropertiesSet() is basically not called by Spring on factory-made beans.

Workarounds exist (eg. calling FactoryBean.getObject() on JtaTransactionManagerFactoryBean directly and exposing the result (the JtaTransactionManager) to the application-context/bean-factory), but that was surely not intended so by the authors. A possible solution would be to make JtaTransactionManagerFactoryBean an InitializingBean and perform the initialization of the actual transaction-manager, when Spring calls afterPropertiesSet() on the factory.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 16, 2019
@bbodnar
Copy link
Author

bbodnar commented Mar 16, 2019

TransactionManagerFactoryBeanDemo.zip

A small demo-application attached to illustrate the problem. Attempting to use the transaction-manager fails with "org.springframework.transaction.CannotCreateTransactionException: No JTA UserTransaction available - programmatic PlatformTransactionManager.getTransaction usage not supported", because the JtaTransactionManager isn't initialized. Enabling the workaround in demo.spring.Config solves the problem (but that is no regular solution).

@sbrannen sbrannen added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Mar 17, 2019
@sbrannen
Copy link
Member

@bbodnar, are you actively deploying your application to WebLogic or WebSphere?

If not, there's no need to use the JtaTransactionManagerFactoryBean: you can instead simply return a new instance of JtaTransactionManager from an @Bean method.

@sbrannen sbrannen added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Mar 17, 2019
@bbodnar
Copy link
Author

bbodnar commented Mar 18, 2019

Yes, the software this is part of is used actively - besides JBoss/Wildfly - on Websphere Classic.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Mar 18, 2019
@sbrannen
Copy link
Member

@bbodnar, thanks for the feedback.

I suppose we could introduce something like a JtaTransactionManagerBuilder (for use with JavaConfig) analogous to the LocalSessionFactoryBuilder that was introduced as a companion to the LocalSessionFactoryBean for Hibernate.

Let's see what the rest of the team thinks.

@snicoll
Copy link
Member

snicoll commented Apr 1, 2019

Would that new high-level type have any other feature than initializing the transaction manager? I'd introduce such a type only if we use the opportunity to add additional features.

@sbrannen
Copy link
Member

sbrannen commented Apr 1, 2019

Would that new high-level type have any other feature than initializing the transaction manager?

No, I don't think it would introduce any new features, and consequently it would not really be a "builder" but rather simply a "factory" (e.g., JtaTransactionManagerFactory).

I'd introduce such a type only if we use the opportunity to add additional features.

Understood.

A possible solution would be to make JtaTransactionManagerFactoryBean an InitializingBean and perform the initialization of the actual transaction-manager, when Spring calls afterPropertiesSet() on the factory.

So what about @bbodnar's above proposal?

Workarounds exist (eg. calling FactoryBean.getObject() on JtaTransactionManagerFactoryBean directly and exposing the result (the JtaTransactionManager) to the application-context/bean-factory), but that was surely not intended so by the authors.

@jhoeller, since you're listed as the sole author of JtaTransactionManagerFactoryBean, what's your position on the matter?

@bbodnar
Copy link
Author

bbodnar commented Apr 1, 2019

A note to my proposal: in Spring's sources there are already few cases, where afterPropertiesSet() on beans implementing InitializingBean is called manually (i.e. not by the bean-factory):

- spring-context-5.1.5.RELEASE.jar!/org/springframework/cache/interceptor/CacheProxyFactoryBean#createMainInterceptor()
- spring-context-5.1.5.RELEASE.jar!/org/springframework/context/annotation/MBeanExportConfiguration#WEBSPHERE#getMBeanServer()
- spring-context-5.1.5.RELEASE.jar!/org/springframework/jndi/JndiObjectFactoryBean#JndiObjectProxyFactory#createJndiObjectProxy()
- spring-tx-5.1.5.RELEASE.jar!/org/springframework/transaction/interceptor/TransactionProxyFactoryBean#createMainInterceptor()

I think, this would be also here the most straightforward solution.

@jhoeller
Copy link
Contributor

jhoeller commented Apr 1, 2019

Indeed, letting JtaTransactionManagerFactoryBean implement InitializingBean, propagating it to the JtaTransactionManager instance, would indeed work. There's a potential conflict with existing workarounds where calling code triggers JtaTransactionManager.afterPropertiesSet (e.g. manually or through exposing getObject() from an @Bean method) since afterPropertiesSet is only to be called once but that's acceptable for 5.2 at least.

@jhoeller jhoeller self-assigned this Apr 1, 2019
@jhoeller jhoeller added this to the 5.2 M1 milestone Apr 1, 2019
@jhoeller jhoeller added the type: enhancement A general enhancement label Apr 1, 2019
@bbodnar
Copy link
Author

bbodnar commented Apr 2, 2019

@jhoeller: thank you for the fix!

@rstoyanchev rstoyanchev removed the status: feedback-provided Feedback has been provided label Apr 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

6 participants