Reputation: 1
I realized after writing this question I could sum it up in a few sentences. How can I manage transactions in Spring-Data-JPA with CDI the same way you would by using @Transactional in Spring itself?
First thing I did was set up Spring Data JPA CDI based on the documentation here. http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/jpa.repositories.html#jpd.misc.cdi-integration
I set this up and it is working fine for read operations but not write operations
For Example, Their example in the docs would work fine.
List<Person> people = repository.findAll();
So I have the basic setup complete.
Written by hand may have typos. This is similar to the code I execute.
@Inject
UserRepository userRepository;
User user;
@Transactional
public void signUpUserAction() {
userRepository.saveAndFlush(user);
}
Then I receive this error
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
At first I realized I did not have the @Transactional so I added it and still did not work.(I believe in spring you need to use the AOP xml file to set up @Transactional so it makes sense this does not work in EE out of the box, I just do not know how to make it work.)
FYI annotating with this does not work
@TransactionAttribute(TransactionAttributeType.REQUIRED)
Something I tried while I was writing this post and I got it to work sort of... but I don't like the code and am still interested in using @Transactinoal, this code feels dirty, I'm pretty sure @Transactional handles calling other methods that are transactional in a clean way while this code would not.
This saves and I verify it's in the database.
@Inject
EntityManager em;
@Inject
UserRepository userRepository;
private User user;
public void signUpUserAction() {
em.getTransaction().begin();
userRepository.saveAndFlush(user);
em.getTransaction().commit();
}
So in short, how can I use @Transactional or something similar to manage my transactions?
Thank you for any help.
Upvotes: 0
Views: 1933
Reputation: 5213
for everyone who have this question yet. I have this experimental project that support @Transactional in a CDI environment. This project uses a custom code of Narayana as interceptor and provide compatibility with it and Spring Data Jpa implementation. Key points to take in consideration:
Custom (Spring Data) Cdi Configuration -> add a Custom Transactional Post Processor custom spring data cdi configuration
Implement a custom Transactional Post Processor: sample of a Custom Transactional Post Processor
Implement a custom Transactional Interceptor sample of a custom transactional interceptor
Add a Cdi Producer for your custom Tx Interceptor cdi producers
Create your custom repository fragments using @Transactional (JTA) custom fragments
Compose your Repository interface extending Repository interface and your fragments with @NoRepositoryBean annotation custom repositories
Take a look at this link that have some tips: tips
Regards,
Upvotes: 0
Reputation: 83051
If you run Spring Data in a CDI environment, you're not running a Spring container at all. So you'll need to use EJB session beans to work with the repositories as CDI currently does not have support for transactions out of the box. The CDI extensions shipping with Spring Data is basically providing an entry point into the JavaEE world and you'll use the standard transaction mechanisms you can use in that environment.
So you either inject a repository into an @Stateless
bean directly or you inject the CDI bean into one. This will allow you to use EJB transaction annotations on the EJB then.
Upvotes: 2