Reputation: 35
I have some junit-style integrationtests, where injection is handled by Weld. I am able to inject an entityManager just fine, and all seems to be fine, when my code under test does some operation on my entityManager...except nothing is actually written to my in-memory H2 database...no inserts, updates anything. This is caused by not having any transactions available from what I can tell. When I launch my test, the logs informs me of this:
Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Is there any normal/typical way of doing this? I have only found this: https://in.relation.to/2019/01/23/testing-cdi-beans-and-persistence-layer-under-java-se/ that comes somewhat close to what I need (I use the @Transactional annotation in code that is being tested) but is seems like having to re-invent the weel. Is there really no simple way of doing this ?
Upvotes: 1
Views: 1484
Reputation: 722
If the UserTransaction
is not available that it most probably means you haven't configured the transaction manager. The @Transactional
and the @Inject UserTransaction
capabilities are defined in the JTA spec which is implemented by a transaction manager.
The Weld is used in WildFly and is well integrated with Narayana. That's one option for you to go (disclaimer: I'm a developer at http://narayana.io project).
As your application runs in standalone mode you will need to provide a little bit integration above. The starting point is adding dependency to
<groupId>org.jboss.narayana.jta</groupId>
<artifactId>cdi</artifactId>
Then you should implement the Weld SPI interface on top of it (example is in the Narayana quickstart here: https://github.com/jbosstm/quickstart/blob/master/jta-1_2-standalone/src/test/java/org/jboss/narayana/quickstarts/jta/cdi/CDITransactionServices.java)
I wrote a blog post about this and you can find more details here: http://jbossts.blogspot.com/2019/04/jta-and-cdi-integration.html
If you have an issue to pull the transaction manager dependency to your project - I understand there could be a worry on extending the list of dependencies bigger or about the some performance impact (even I consider this worry baseless, but it's a different discussion) - then you will need to configure your EntityManager
to run with the local transaction. Using <non-jta-data-source>
could help here.
Hibernate needs to run the insert query inside of a transaction. It's a prerequisite.
Be aware that if you configure EntityManager
to use resource local transactions the tests could start working but still you can't use the @Inject UserTransaction
or @Transactional
as they are capabilities provided by Transaction manager.
Upvotes: 3