Spring's JdbcTemplate and Transactions - java

When using JdbcTemplate, do I need to explicitly configure transactions?
My code layout looks like the following:
I will have a UserDao that will be injected into my UserService, and then my Controllers will make calls on methods in my UserService.
I want to keep things as simple as possible transaction wise, and I don't need multiple database calls to span a transaction.
By default, do I have to do anything in my configuration file or use a #Transaction annotation anywhere?
Now say in my controller I need to make 2 calls on my userService and accountService, could I explicitly wrap it in a transaction somehow?
userService.updateUser(user);
accountService.updateXXX(...);

Yes, JdbcTemplate is not a substitute for transaction management. You still benefit from database transactions, so userService.updateUser will operate in a database transaction, but if accountService.updateXXX fails, userService.updateUser will not rollback.
If you don't want to use AOP, you can use TransactionTemplate instead. See programmatic transaction management in the Spring Reference Documentation.
One pattern I've seen before is for the MVC controller class to invoke a business service, which encapsulates the operation. The method of the business class could then be annotated #Transactional.

If your controller wants to do several things with users and accounts and have all that happen within one transaction, then you should have a service with one method that does all that stuff. Creating one service per DAO is not a great idea, because you end up with do-nothing wrappers around DAOs and processing will be slow because the database will have to create a separate transaction for each call to a DAO, you're making it do a lot more work than it should have to.
The service should provide functionality to the controller or whoever else is calling it. I try to create services with the idea that the service provides specific functions useful to a certain type of user.

Related

Behavior of entityManager when using SpringDataJpa with Hibernate/eclipselink

I want to use a mix of SpringDataJpa and Eclipselink/Hibernate for persistence in my application. Till now, I have come across an approach detailed here. What I want to is use Spring Data JPARepository for CRUD operations and use a conventional #Repository bean for more complex queries or other functionality. It is important that I ensure the same entityManager is used for both, the usual method calls to the #Repository class and calls to the spring JpaRepository interface (class generated by spring).
My setup is done as in the example given here.
Don't.
Why would you split the repository bean in two (from the perspective of the user of the repository). You can have custom methods in your repository of which you completely control the implementation.
If you really want to you can always inject an EntityManager in other classes and if they participate in the same transaction (and you don't have some really weird setup) you will using the same single EntityManager in all places.

Java service transaction practice

We use to define transaction using #Transactional annotation or else way to défine transactions.
We also use to define a transaction on a service or specificaly on its methods.
Recently, a colleague suggested no to set transaction on services but on the caller (remote controller for angular, batch, IHM controller like jsf...).
I found this approach interestings.
What do you think about this ?
You probably need both. Services should be transactional, or at least SUPPORTS for reads / selects. But, in the web controller or other top-level layer you also need transactions if you call more than one service.
Note, however, that if you controllers are concrete classes, you are going to need to use AOP or other proxy mechanisms to wrap functions in a transactional layer. The other option is to just autowire in a TransactionTemplate into your controllers and do TX management manually where you need it.
Obviously the TX template approach means you have to be careful to actually use it when needed. With the proxy approach you can just make every controller function transactional. But the overhead may be more than you want if there are only a few functions that make more than one service call.

where to define transaction boundries in java (#Service or #DAO level), Any Suggestions

where to define transaction boundries in java (#Service or #DAO level), Any Suggestions
We need to manage transaction between multiple services.
Depending on your persistence technology some kind of transactions might be needed to persist anything at all. Thus you may want a transaction on a DAO-level for e.g. testing the DAO layer. If e.g. controllers have direct access to DAOs you'll need transactions on DAOs, too.
What you may want to do is declaring a transaction on the service-level and the DAO-level reusing a provided transaction.
Read the great spring reference on transactions as well as the spring data reference for ideas.
Usually I recommend to use Transaction in Service, but it depends on....
In case of Service,you will get ability to create batch of actions in the one transaction.
For example start transaction. read, modify more than one entities, update, delete whatever. close transaction.

Using Services and DAOs in spring mvc controller

I'm building a web application that primarily constitutes of CRUD operations of data from back end/database. There are instances where in I have to write business logic(I'm sure we will have more business logic built as we go deeper in to development). Currently for each UI screen I'm creating I create a model class,Service class, DAO class, a controller(it's servlet essentially) and bunch of jsp pages. In most cases the service class just calls the methods from DAO to pass in model objects. Essentially we use model classes to map data from UI screens. Hence the controller will have the model objects populated when a form is submitted. I have started using service classes to keep a separation layer from web layer to DAO layer. But at times I feel that the service class is just adding unnecessary level of API calls, I would think that I could just inject the DAO in to Controller and complete the task faster. I want to use the service class only when there is additional business logic to be performed. If you have to design an application what factors do you consider using controller->DAO vs controller->Service->DAO control flow?
DAOs are more granular and deal with one specific entity. Services provide macro level functionalities and can end up using more than one DAO. Typically, Services are used for defining transaction boundaries to gain atomicity. In other words, if you end up updating multiple tables using multiple DAOs, defining transaction boundary at service will help in either committing or rollbacking all the changes done to DB.
In your design, since you are primarily doing CRUD for various entities, it may seem that services are not adding much value. However, think of web-based front end as one way of updating data. Usage of services will allow you to expose same capabilities as a web-service later to other forms of client like third party integrators, etc.
So, in summary, your design seems to be in line with conventional practices. If you feel that you can combine multiple services into one based on some common theme such that it can reduce the overhead of code, then, you should go ahead and do it. At the end of day, ultimate goal is to create maintainable code which no one is afraid to change when need arises.
In Pro-Spring-3 book they mentioned below line, for controller with JPA2
Once the EntityManagerFactory had been properly configured, injecting it into your service layer
classes is very simple.
and they are using the same class as service and repository as in below:
package com.apress.prospring3.ch10.service.jpa;
// Import statements omitted
#Service("jpaContactService")
#Repository
#Transactional
public class ContactServiceImpl implements ContactService {
private Log log = LogFactory.getLog(ContactServiceImpl.class);
#PersistenceContext
private EntityManager em;
// Other code omitted
}
but in case you are going to use spring-data CRUDRepository or JPARepository then your DAO will be Interface and you have to make service layer to handle your code
I'd reference my answer here
The long and short of it is the advantage of using a Service layer is it gives you room to move in the future if you want to do anything with Spring Security and roles etc. It allows you to handle transactions more atomically and Spring itself has really nice annotations for this.
Use a service class when dealing with more than one aggregate root.
Inject repositories (aka a dao that returns a collection) or dao's directly into controller, no need for an extra layer/class to do a basic get.
Only use service classes where necessary, otherwise you have twice as much code as required.
You can make repository generic, and annoatoate with #Transactional(propagation = Propagation.REQUIRED) which enforces a transaction is present, but won't create a new one if already present. So if you later use multple repositoes in one service class method, you will only have the one transaction.

On services and #Transactional

If I have a service class which calls three other service classes in a row, and each of those sub-services has to deal with a DAO object at some point, how can I make so that the wrapper service wraps them all into a single transaction? Will it be as simple as annotating the wrapper with #Transactional? What if the DAO is already marked as #Transactional?
The default transaction propagation in Spring framework is REQUIRED, which means that the transaction is created if it does not already exist or the code joins existing one:
Support a current transaction, create a new one if none exists. Analogous to EJB transaction attribute of the same name.
This is the default setting of a transaction annotation.
This means that if you wrap calls to three transactional methods in a single transactional method, they will all run within a single transaction. Just like that.
See also:
What is the right way to use spring MVC with Hibernate in DAO, sevice layer architecture
If you annotate the outer service as #Transactional and your DAOs are also #Transactional and called by the service they will by default join the outer transaction as you're hoping.
this is actually a question about nested transaction (http://en.wikipedia.org/wiki/Nested_transaction). with spring, (assume you are using version 3 and annotation), REQUIRED is default for transaction mode. If you set this model for your service methods, all methods wrapped by your "wrapper" service will use the host transaction, which means they will run in same transaction.

Categories