Reputation: 4040
I am writing an application providing REST services (with Apache-CXF) that manage JPA entities (with Hibernate).
I am a bit lost with Transaction management and would like your advice on this topic.
For now, I have put an intermediate layer between my business REST services and the lower services, solely for transaction management purpose.
Currently, my code looks much like that :
@Service
class PersistanceService<MyBusinessClass>{
MyBusinessClass load(Long id);
void save(MyBusinessClass businessObject);
}
@Service
class BusinessService<MyBusinessClass>{
void doSomethingOn(MyBusinessClass businessObject);
}
@Service
class TransactionBusinessService<MyBusinessClass>{
@Transactional
void doSomethingOn(Long id) {
MyBusinessClass businessObject = persistanceService.load(id);
businessService.doSomethingOn(businessObject);
persistanceService.save(businessObject);
}
}
@Service
@path("/foo")
class RESTService {
@Path("/doSomething")
void doSomethingOn(Long id) {
transactionBusinessService.doSomethingOn(id);
}
}
I think the TransactionBusinessService is overkill. I would like ''Spring'' or ''CXF'' to handle transactions for me : I feel that a request is the good granularity to do so : Init an entity manager at the beginning of each request, and commit updates at the end.
I've tried to add the @Transactional annotation to the REST methods themselves, but it seem to be ignored, or to conflict with CXF.
Thanks in advance for you advice.
Upvotes: 2
Views: 2842
Reputation: 4440
Do you think it is a good idea to delegate the transaction at the request level and not to bother about it anymore ?
Usually it's not good idea, because:
for-loop
, each of which has to have own transaction, it's also not
that transparent; meanwhile on service layer you may decide whether you need the whole loop to be transactional or each of iteration;tx:annotation-driven
(and some other AOP-interceptor) sometimes works a bit unpredictable, if you are using AOP annotations in the controllers directly (at least I faced such issues in Spring MVC/struts2 and some other frameworks)So basically, you have 3 layers:
@Transactional
, @PreAuthorize
, @Cacheable
and so on), which use persistence layer within;How can I have Spring or CXF bind the transaction management to the requests for me?
Please make sure, that you:
TransactionManager
('org.springframework.transaction.PlatformTransactionManager` implementation) in your configtx:annotation-driven
in your config<bean name="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven transaction-manager="txManager"/>
Upvotes: 3