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.
Related
We got this design:
Rest Controller -> Calling Service -> Calling JPA DAOs
Let say we save employee. And we have a requirements to validate employee name.
IEmployeeService.saveEmployee(Employee emp)
EmployeeController.saveEmployee(Employee emp)
Option 1: I can inject JSR303 annotations on Employee and Let Rest Controller validate it as part of automatic validation.
Option 2: I validate in service method and raise exception and let controller to return proper JSON of that exception.
Seems like service should have validation anyways... but in presence of JSR303 annotations controller is doing everything, hence there seem to be duplication of logic if service does those checks as well.
How do you approach? Everybody's comments welcome and will be appreciated.
Thanks
Babar
IMHO, the standard way is to use both Opt 1 and Opt 2.
But, you have to define what's going to be validated in each layer.
This is my favorite approach:
Validate field constraints in Controller. This include: Date format, string length, min, max, null... validation
Validate business logic constraint in Service. Include: Unique, exist check, from date < to date, max items per group of entities...
One side note: Entity should never been exposed to outside world. We should have some kind of converter logic to convert entity to output JSON/model
Ideally your web facing part should have your validation logic implemented. The service layer should be purely for the business part of project. It is also security best practice before it reach to your service layer code. Nowadays people do mix-up layer and want to do everything in same layer. The jsr-303 annotation are bean level validation. So normally it is applied at a place where model comes into picture.
So you can do that at
controller layer: to validate your input and other min/max range and basic validation.
service layer: To have any specific validation at service layer by Autowiring javax.validation.Validator.
I would do both.
In your example you seem to have both methods refer to Employee, which might be possible in very simple scenarios, but in practical scenarios this is not.
It is more likely that you are going to have an EmployeeDTO which has JSON properties mapped to Java object fields. You might even have more specific DTOs to specific employee operations (for example change password), depending on what forms your UI is exposing. This will be received by your controller, and JSR303 can help do syntactic validations, like checking the string is not empty, that a name does not contain numbers etc.
The DTO should not bleed in to the service, but its data should be translated to whatever the service is expecting, which should be decoupled from the inputs of the controller.
Your Service will then receive an Employee. This could be a JPA Entity if it makes sense, or some other intermediate domain object related to the operation being performed. The creation of the Employee should ideally already enforce some simple checks (for example non null checks), to ensure that the object is consistent after construction. The service itself should then validate what it is receiving, independently of what the controller validates. The service could be used by other controllers, or invoked by other services in the future, so you should always program defensively. The service could also do more logical checks (for example does another employee with the same ID but different details exist? etc.) This will do business logic validation that will enforce further robustness.
If you see a lot of common code between the DTO and the Entity, or intermediate objects, there are also mapper utility libraries which can help you avoid repetition, like MapStruct.
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 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.
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.
What would you suggest as a good and practical but simple pattern for a solution with:
HTML + JSP (as a view/presentation)
Servlets (controller, request, session-handling)
EJB (persistence, businesslogic)
MySQL DB
And is it necessary to use an own layer of DAO for persistence? I use JPA to persist objects to my DB.
Should I withdraw business logic from my EJB? All online sources tell me different things and confuses me...
I would definitely put the business logic in Stateless Session Beans. Stateless session beans are nice as they nicely capture the transaction boundaries. And it decouples the View layer from the persistence layer.
Take care that the methods of the SSB correspond to small business goals the user wants to achieve.
Another point is that you must be sure that the data you return has all data in the object tree and that you do not rely on lazy loading to get the rest, because this causes all kind of problems.
Stay as far away as possible from Stateful Session Beans : they are bad news and are a broken concept in the context of a web application.
For long running things, consider using Message Driven Beans which you trigger by sending a JMS message. These are a nice way to do background processing which frees the business logic faster, keeps transactions shorter and returns control to the end user faster.
What would you suggest as a good and practical but simple pattern for a solution with JSP/Servlets + EJB + MySQL
Use the MVC framework of your choice, Stateless Session Beans for the business logic and transaction management (prefer local interfaces if you don't need remoting), Entities for persistence.
Inject your EJBs wherever possible (if you are using Java EE 6, this means anywhere and you can also skip the interface).
And is it necessary to use an own layer of DAO for persistence? I use JPA to persist objects to my DB.
Some might say yes, I say no in most cases. The EntityManager already implements the Domain Store pattern, there is no need to shield it behind a DAO for simple needs.
You might want to read the following resources for more opinions on this:
Has JPA Killed the DAO?,
JPA/EJB3 killed the DAO,
and the more recent DAOs Aren't Dead - But They Either Collapsed Or Disappeared
Should I withdraw business logic from my EJB?
I wouldn't. Put your business logic in your (Stateless) Session Beans. EJB3 are POJOs, they are easily testable, there is no need to delegate the business logic to another layer.
Anno 2012 I would not recommend going for Servlets and JSP as the presentation layer. This was all the rage in 2002, but that's a decade ago.
Today Java EE has an excellent MVC framework build in called JSF. You are much better off using this instead. You most likely want to fetch some Widgets from the component library PrimeFaces, as all the standard ones are a bit basic. A utility library like OmniFaces is a great addition as well.
Regarding the DAOs; don't go as far as directly using the entity manager in (JSF) backing beans, but if you are already using Service classes (transactional boundaries) for your business logic , using a DAO as well might be overkill.
There are still some small advantages of a DAO, like a dao.findByName(...) looks a little clearer than loading a named query, setting a parameter, and getting a (single) result, but the cost is that you have to maintain a seperate DAO for each Entity, probably in addition to some Service.