I am using JAX-RS to provide an HTTP interface for managing a data model. The data model is stored in a database and interacts via JPA.
This allows me to modify the interface to the data model in accordance with the requirements of REST clients and, apparently, works very well. However, Iβm not sure how to handle the scenario in which the method provided by the JAX-RS resource requires a transaction that affects the JPA template get, update, commit-on-tx-end, since there is only transactional packaging the get operation, so the update never not executed. I see the same problem if a single REST operation requires multiple JPA operations.
Since I am using Spring transaction support, it is obvious that you need to apply @Transactional
to these methods in JAX-RS resources. However, for this to work, Spring needs to manage the JAX-RS resource lifecycle, as well as the use cases that I know that resources are created using βnewβ when necessary, which makes me a little nervous anyway .
I can think of the following solutions:
- upgrade my JPA methods to provide a transaction-driven version, all I want to do is using my REST interface. It should work, holds transactions from the JAX-RS level, but prevents the creation of the get, update, commit-on-tx-end template and means that I need to create a very granular JPA interface.
- Inject Resource Objects; but they usually have a state with at least the identifier of the object interacting with
- Abandon the hierarchy of resources and add large, stateless super resources at the root that control the entire hierarchy from that root; not cohesive, great services
- Have a hierarchy of indexed, apartheid, transaction-supporting auxiliary objects that are βshadowβ actual resources; resources are created and stored, but delegate method calls to auxiliary objects.
Anyone have any suggestions? Maybe I missed some key point somewhere.
Update - to get around the lack of a transaction around the get, update, commit-on-tx-close thread, I can expose the EntityManager merge method (object) and call it manually. Not neat and does not solve a larger problem.
Update 2 @skaffman Code Example: In the JPA service layer, injected annotations work
public class MyEntityJPAService { ... @Transactional(readOnly=true)
No new transactions in JAX-RS resource created by new
public class MyEntityResource { ... private MyEntityJPAService jpa; ... @Transactional