Spring Transaction

For example Employee class is there & I want to save employee details in DB. For that I should create 2 interfaces (EmployeeDAO & EmployeeService & I need to implement the methods in respective Impl classes (EmployeeDAOImpl & EmployeeServiceImpl).

2. Why to use @Transactional annotation (I know by using it we can work with Hibernate, JPA etc) but we can create other DaoImpl classes by using JDBC/Hibernate/JPA & let serviceImpl to call them. Here serviceImpl class simple calls the saveEmployee() method of DaoImpl. Then what s the advantage of using @Transactional?

3. In some forum I read that I need to write business logic in service class. What kind of business logic to write?

Some believe that there should always be a service layer and a repository layer. I come from the camp that if there is no service logic to be done then it basically becomes what I call a pass-through service to the Repository. In this case I would not bother with the service layer as it does not add any value.

Geeta Puttappanavar wrote: 2. Why to use @Transactional annotation (I know by using it we can work with Hibernate, JPA etc) but we can create other DaoImpl classes by using JDBC/Hibernate/JPA & let serviceImpl to call them. Here serviceImpl class simple calls the saveEmployee() method of DaoImpl. Then what s the advantage of using @Transactional?

@Transactional is just a declarative way to declare a transaction. Often times it is used in the service layer but if all you are doing is saving an object with no other business logic, there is no reason why the @Transactional could not live on the save method in the repository and just be called directly. However if there is service logic it makes sense for this to live in the service layer. Imagine you have a service with something like this.

In this case myReposiory.save and myRepository.update may or may not be annotated with @Transactional but in this case I want both save and update (an maybe some other stuff) to happen in a single transaction and roll all of it back if it fails. My service layer would worry about service stuff and delegate to the repository for making the queries.

Geeta Puttappanavar wrote: 3. In some forum I read that I need to write business logic in service class. What kind of business logic to write?

Depends on the application. There maybe lots of stuff going on or it may be as simple as grouping repository operations together, potentially wrapping them in a single atomic transaction.

These are Spring stereotype annotations. One thing they offer is for beans to automatically be created when they are detected with a component scan. The @Repository annotation add Springs DataAccessException translation so you no longer need to deal with the messy SQLException. @Service will possibly add more Spring features in the future but beyond what I have stated it is also useful for AOP and defining pointcuts.

Some believe that there should always be a service layer and a repository layer. I come from the camp that if there is no service logic to be done then it basically becomes what I call a pass-through service to the Repository. In this case I would not bother with the service layer as it does not add any value.

Geeta Puttappanavar wrote: 2. Why to use @Transactional annotation (I know by using it we can work with Hibernate, JPA etc) but we can create other DaoImpl classes by using JDBC/Hibernate/JPA & let serviceImpl to call them. Here serviceImpl class simple calls the saveEmployee() method of DaoImpl. Then what s the advantage of using @Transactional?

@Transactional is just a declarative way to declare a transaction. Often times it is used in the service layer but if all you are doing is saving an object with no other business logic, there is no reason why the @Transactional could not live on the save method in the repository and just be called directly. However if there is service logic it makes sense for this to live in the service layer. Imagine you have a service with something like this.

In this case myReposiory.save and myRepository.update may or may not be annotated with @Transactional but in this case I want both save and update (an maybe some other stuff) to happen in a single transaction and roll all of it back if it fails. My service layer would worry about service stuff and delegate to the repository for making the queries.

Geeta Puttappanavar wrote: 3. In some forum I read that I need to write business logic in service class. What kind of business logic to write?

Depends on the application. There maybe lots of stuff going on or it may be as simple as grouping repository operations together, potentially wrapping them in a single atomic transaction.

These are Spring stereotype annotations. One thing they offer is for beans to automatically be created when they are detected with a component scan. The @Repository annotation add Springs DataAccessException translation so you no longer need to deal with the messy SQLException. @Service will possibly add more Spring features in the future but beyond what I have stated it is also useful for AOP and defining pointcuts.

Hi Bill,

Thank you so much for quick reply. That s a very good explanation. I understood it very well. If I get any other doubts again I'm gonna ask you.

IMO you should always have a service layer or at least some layer of abstraction between client code and the data layer. This reduces the chances that changes to the data layer will have an impact on client code. A client should not be coupled to the data layer.

It is an interesting discussion and has been debated before there are definitely 2 camps on this issue. Awhile back I recall one of the Springsource developers posted an example MVC application on the Spring blog I think it might have been Josh Long and there was some discussion about the way he @Autowired a repository directly in the controller, and Keith Donald (wrote large parts of Spring MVC and Spring Webflow) chimed in and said that at Springsource they do not do pass-through service methods. There was of course a lot more reasoning given but I can't find the link.

In any event n-tier architecture (here we are mostly talking about 3 tiers) addresses the issue of separation of concerns. My view is largely the same one I have for premature optimization. If you are dealing with a simple application in which there are no service layer concerns than it is not necessary.

So if I have a simple controller that takes a person and stores it directly to the database.

Now I will of course have a PersonRepository that takes care of the details of getting the data into the database and nothing else. What do I put in my service layer? Do I create a PersonService Interface defining a PersonService save method that does nothing but @Autowire in PersonRepository and call save? In this case I think doing this complicates the code by adding a functionally useless method just for sake of having a service method in between. My opinion is that this reduces maintainability and increases complexity by adding in an unnecessary abstraction.

Now service code does not belong in the controller or in the repository so when it is not that simple then certainly I will add the service method. As a matter of fact, 99% of the time my controller calls some method in the service layer but I will not put one line methods in my service implementations to call a repository which I think is what the OP was asking about.

IMO changes can still be made to the data layer without affecting my controller, because that bit is abstracted by the repository and exposed through an interface which should not be changed. If the interface is changed something is going to have to be changed in another layer regardless. Whether that is in a one line service method or my controller does matter much to me, it seems like 6 of one or half dozen of the other.

Strict adherents to the n-tier architecture patterns will state that controller should always pass through the service layer to access the data layer. I can respect the varying philosophies out there but for me at least absolutes very rarely are absolute and I would require more convincing to change my view on this particular issue

In the tiered architecture the model/domain box is usually a vertical box along the side spanning all the tiers. These would be the objects that are used to pass information back and forth, they are simple POJO's. Whether the object is annotated or not it is still just a POJO with some extra metadata. The idea when JPA was created was to be able to use these objects between the layers even from one virtual machine to another and back again.

I did see you said "managed entity" so forgive me if I misunderstood you. The transaction democratization should most certainly be confined to the service layer or in this simple case the data layer, that way when you exit from the save method all you have in your controller is a POJO (detatched entity) which can then be modified perhaps in a (UI form) until it eventually makes its way back to the data layer and is reattached and merged into the context.

That said I do often times map entities to DTO's to restrict the amount of data I expose to the UI but there are many who would disagree with DTO's as well