I have a struts project and my client give me full business logic classes.He need this ingrate with struts and hibernate.
Which is best,
to put the business logic to my Dao layer , need to add an addtional service layer for business logic.
Some struts project i found that the action class directly access Dao.
Please suggest me which is better choice.help is highly appreciated.
Thanks,
My suggestions is to keep Dao clean from your business logic but yes all the database related logic and customization should write at DAO layer like all hibernate logic, Casting of result into your Classes etc.. (As you are using Hibernate) should be written in DAO.
And whole iteration, setting/getting, result customization, preparation, request improvement to work as parameter for hibernate query should be written at service layer.
One another layer Controller should work over service layer which will receive request and call respective service Method and provide generated response.
I would highly suggest to write your business logic into service layer, so that your dao layer contains only database interaction and could be reusable at any point of time.
Also I would recommend you to add one presentation layer (all entities with plain values) that will be accessed by UI layer.
Let Hibernate be your DAO layer and write a service layer over that which contains your business rules. Those two together make up the model part of MVC. The Struts actions are the controller part of MVC.
Related
Let's say we have some layer above service layer, with web controllers for example. Service layer is in turn above DAO/Repo layer. In the upper layer the service calls are used alongside repo calls. It breaks the layering of the application to some extent, but should we really bother about wrapping repo methods like findAll() into service methods. I don't think so. Are there any drawbacks that might cause a lot of pain because of such design? Transactional issues?
I would turn your question around and say - why not have a service layer for such a method? Is it such a pain to wrap a DAO method like:
public class PersonService {
...
private PersonDao personDao;
...
public List<Person> findAll() {
return personDao.findAll();
}
...
}
Client data
What if you don't want to send back the data entity that represents a Person to your controller? You could map the data in the service layer to an Object that only clients are dependent on.
Coupling
You are also coupling your layers. The controller layer should only depend on the service layer and the service layer should only depend on the DAO layer.
Transactions
All transactions should be handled at the service layer (as a service method may call multiple DAO methods).
Business Logic
All business logic should be in your service layer. Therefore, you should never bypass such logic by calling a DAO directly.
I know, for a method like findAll, it seems pointless but I think the point about layer coupling defeats that argument.
Yes it can be a pain if some developer used to call DAO layer code directly from other layers i.e. other than Service layer or whatever architecture you are following for this as a solution:
Use maven dependencies create 4-5 different modules for your project and mention the dependencies in pom.xml so that no calls will be made from any other incorrect layer.
For making it more clear:-
If you want to access layer 3 only from layer 4 just add one dependency entry in layer 3 for 4 and as no other modules have access to layer 3 they can't call code from it.
You definitely get hundred of example for doing this.
Suppose the architecture is such that there is
Struts framework or jersey resource
Facade layer
Business layer
Data access object layer DAO
Though the Input field validation is to be done at presentation layer i.e Struts Action class or jersey resource class
But my question is where should business level validation to be done and same outcome to be passed to UI.
I.e suppose resource is
employee/{employeeId} method DELETE
Now first need to verify that employeeId exist or not , so for that validation should be done at resource level, facade level or business level and how it should be any best practice is highly appreciated.
Also please note that this business validation require DAO layer access since to check in DB if employeeId really exist.
Thanks in advance
There are as many arguments as approaches for what you're asking. I prefer to leave validation to the business layer and let the service layers above that more or less just handle routing and error reporting. Good luck!
Depends on the architectures and frameworks you have choosen.
In example: If you have one Database but a server-farm, the Validation should be more near the Database. If you can lock/unlock the Database in the DAO, you shall lock the employee-row first before you validate.
Also it depends on the configuration:
If you use optimistic or pessimistic locking.
If you have a #version field on the entitys.
many many more.
I suggest you to write logic related database access at dao layer, which returns the result to service layer and it returns to the Action class. And you should validate it in your action class.
I have design issue when implement 1 simple web application.
I use struts2 web controller, spring’s IOC and Hibernate as persist layer.
Because this web application is very simple at begging. So I only have 2 layers:
1 DAO layer which used to access database. Almost every table have related DAO.
2 Action layer. User struts2.
I am satisfy with this architecture because can quickly implement my web application.
As project become bigger, I found the action layer become big and complex, and very hard to re-use.
I try to create service layer, to solve complex business logic is good, but my application still have a lot of simply logic. E.g: Load 1 object, save 1 object, and get collection by some condition and display it to webpage. If give each simple DB access method have corresponding service method. Still cost a lot of effort. How can solve this issue?
And I think, if service layer existing, direct call DAO layer still not good design for my application.
Is any good solution for this kind of small web application?
When planing the different layers in a web application it is good practice to explicitly protect attributes and associations in your model from being manipulated without providing an identity context.
This is something that should neither be done in the DAO layer nor in the Controller. You should wrap your DAO layer in a service layer and have the controller only talk to the services not the DAO directly.
Protecting your model against unwanted manipulation means that you for instance adapt the amount of information passed in a data structure between Controller and Service to the actual operation that you want to perform.
For instance: adding or removing an element from a collection is an explicit operation in the service, it does not happen implicitly by manipulating a collection as a member of a DAO object and passing that DAO back into the service.
Instead your service may look like this:
+ getAllCompanies(): CompanyType[*]
+ getAllEmployeesOfCompany(c: CompanyType) : EmployeeType[*]
+ addEmployeeToCompany(e: EmployeeType, c: CompanyType)
+ removeEmployeeFromCompany(e: EmployeeType, c: CompanyType)
The additional benefit of such an architecture is that the service layer serves as boundary for your transactions. Using the methods of your controller as boundary for your transactions is in fact a very bad habbit. You could even call it an anti-pattern. Why? Because for instance it would mean that when your client hangs up it would roll back your transaction. That is clearly unwanted in 99% of the cases.
As #mwhs commented, Apache Isis provides plenty of guidance on layering your app. To figure out whether it fits your requirements, you could run through this tutorial I presented at a recent conference.
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.
i examine lots of samples but i didn't find an adequate solution for this.
Some documents say "Ideally your business logic layer shouldn’t know there is a database. It shouldn’t know about connection strings or SQL."
I found some samples which locate the business logic to #Service annotated classes but they use SQL/HQL in #Service methods.
What should be the ideal usage? If we want to change database or persistence technology should we change only #Repository annotated classes or both of them?
I prefer putting all persistence-related stuff (i.e. queries, and everything dealing with JDBC, JPA or Hibernate) in a DAO layer, and have the service layer rely on this DAO layer for persistence-related stuff.
But the main goal is not to be able to change the persistence technology without affecting the service layer. Although that could be possible if you switch from Hibernate to JPA, for example, it wouldn't be if you switch from JPA to JDBC, for example. The reasons are that
JPA automatically persists all the changes made to entities without any need for update database queries , whereas JDBC doesn't, and thus needs additional update queries
JPA lazy-loads association between entities, whereas JDBC doesn't
...
So changing the persistence technology will affect the service layer, even if all the persistence stuff is isolated in DAOs.
The main advantages of this decoupling, IMHO are
clearer responsibilities for each class. It avois mixing persistence-related code with business logic code.
testability: you can easily test your service layer by mocking the DAO layer. You can easily test the DAO layer because all it does is executing queries over the database.
In your service methods you shouldn't use any SQL/HQL syntax or any database work. All of them should be in DAO layer which are annotated as #Repository. You should just call them from your service methods. In this way, you can easily change your db in future. Otherwise, it would have too much burden
Ideally your business logic deals with or consists of objects that model the domain. It shouldn't be aware of the issues of persistence etc. . That's what O/R-Mapper like hibernate are all about. The business logic demands required objects, based on domain attributes (like Employee name, last month's revenue ...).
The persistence layer should be able to translate the business demands into SQL/HQL/Service calls or whatever the used technology requires. Therefore the business logic layer only changes when the business logic changes.
That would be the goal in an ideal world, but in reality it won't work for non-trivial problems. You can't avoid some degree of coupling. But as #JB Nizet said, it pays off to reduce the coupling to a reasonable amount. Using TDD and adhering to OO principles like SRP will help you get there.