I am developing web application with Java EE 6. In order to minimize calls to database will it be a good idea to have classes:
Data access class (DAO) will call only basic methods getAllClients, getAllProducts, getAllOrders, delete, update methods - CRUD methods.
Service class which will call CRUD methods but in addition filter methods e.g. findClientByName, findProuctByType, findProductByYear, findOrderFullyPaid/NotPaid etc... which will be based on basic DAO methods.
Thank you
In my experience (albeit, limited) DAO classes tend to have all the possible database operations which the application is allowed to perform. So in your case, it will have methods such as getAllClients() and getClientByName(String name), etc.
Getting all the users in your DAO and iterating all over them until you find the one you need will result in unneeded waste of computational time and memory consumption.
If you want to reduce the amount of times that your database is hit you could, maybe, implement some caching mechanism. An ORM framework such as Hibernate should be able to provide what you need as shown here.
EDIT:
As per your comment question, no, your service will not be made redundant. What one does is to usually use a Service layer to expose the DAO functionalities. This will, basically, not make the DAO visible from the from front end of your application. It usually also allows for extra methods, such as, for instance, public String getUserFormatted(String userName). This will make use of the getUserByName function offered by the DAO but provide some extra functionality.
The Service layer will also make itself useful should there be a change in specification and you now also need a web service to interface with your application. Having a service layer in between will allow the web service to query the DAO through the Service layer.
So basically, the DAO layer will still worry about the database stuff (CRUD Operations) while the service will adapt the data returned by the DAO without exposing the DAO.
It's hard to say without more information, but I think it's probably a good idea to leverage your database more than with just CRUD operations. Databases are good at searching, provided you configure them correctly, so IMHO it's a good idea to let your database handle the searching in your find methods for you. This means that your find methods would probably go in your DAOs...
It's good to think about/be aware of the implications of DB access on performance, but don't go overboard. Also, your approach implies that since your services are going to be doing the filtering, you are going to load a large amount of DB data into your application, which is a bad idea. The bottom line is you should use your RDBMS as it is intended to be used, and worry about performance due to over-access when you can show its a problem. I doubt you will run into that scenario.
I would say that you're better off having your DAO be more fine grained than you've specified.
I'd suggest putting findClientByName, findProuctByType, findProductByYear, findOrderFullyPaid/NotPaid on your DAO as well in some way because your database will most likely be better at filtering and sorting data than your in memory code.
Imagine you have 10 years of data and you call findProductsByYear on your service class and it then calls getAllProducts and then throws away 9 years of data in memory. You're far better off getting your database to only return you the year you are interested in.
Yes, this is the right way to do it.
The service will own the transactions. You should write these as POJOs; that way you can expose them as SOAO or REST web services, EJBs, or anything else that you want later on.
Related
When creating a entity with the Jhipster helper, it asks
? Do you want to use separate service class for your business logic? (Use arrow keys)
> No, the REST controller should use the repository directly
Yes, generate a separate service class
Yes, generate a separate service interface and implementation
In which case should I use which option?
What are the benefits and flaws of each solution?
Is it possible to change easily the architecture once everything is set?
IMHO it depends on how complex your application is going to be and how long you plan on having to maintain it.
If your domain model is quite simple and your REST controllers are straightforward CRUD operations without complex mapping, you can get away without using a separate service layer.
If your domain model or interactions get more complex, you might need a 'Separation of Concerns': your Controller classes should just map REST calls from/to the correct DTO's for the REST API, and business logic and coordination between different entities should go in a service class that does not have anything to do with the REST API. In the long term, that makes it easier to make changes in the REST API separate from changes in the business logic.
Some blog posts to read:
https://www.petrikainulainen.net/software-development/design/understanding-spring-web-application-architecture-the-classic-way/
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
Then about the decision to use interfaces or not. The main advantages of using interfaces used to be that it allowed better testing and avoided coupling modules too close. But since 2010, there has been a lot of discussion whether it's worth the overhead. Maybe start reading the discussion underneath Adam Bien's original post:
https://www.adam-bien.com/roller/abien/entry/service_s_new_serviceimpl_why
There is a pattern of making a DAO interface before DAO implementation. I googled the advantages of this pattern and one striking point was to support multiple databases.
Now, what i could understand is that multiple databases here means different database engines rather than multiple datasources. Obviously multiple datasources should not have affect on how DAO implementations are made out of DAO interface.
My question is what can be the situations where we may need to support multiple database engines catering the same data? Also if such need arises, how will the REST endpoints be managed to support different databases?
Will they be like for e.g. /db1/courses/, /db2/courses ? Do correct me if i have made any wrong assumption or statement in this question.
I just wanted to add my answer to this about beginning Spring development. This is one of the things that initially will not make sense at first. You will end up asking yourself:
There will be only 1 database, so this doesn't make sense why do it?
Why would I define an interface when there will only ever be 1 implementation?
But really neither of these are really why you do this. But it is the convention and pattern and this style is just what people are use to and you will like it better overtime. There are some other reasons too:
Spring Data - this is an alternative to using an entity manager, whereby you only define interfaces and Spring will actually create beans which implement your repository functionality for you.
Design - ensuring you define an interface will help keep your repository a repository.
Easier Mocking - although arguably you can still do this in Spring without needing to define an interface it is still a bit cleaner when you want to replace the implementation with another.
But really it is just the Spring way, people will find it easier to understand your code if you do this.
I came across this situation where I had to check two DBs and get the data. The other DB was a back up one.
So this was the flow.
RestController --> Service --> DBService
--> DB1Repository --> Connect to DB1
--> DB2Repository --> Connect to DB2
We can design as we want, all it matters at the end is that we follow SOLID principles.
Basically the high level components should not depend on the low level components, but both should depend on the abstractions.
Ill pop in here to describe a real world example.
We recently wanted to change out a large production database (Oracle) to a different one (SQL Server).
For different areas of the database, we had different DAO interfaces and implementations. For example, CustomerDAO, AccountsDAO, etc.
For each interace (like CustomerDAO) we had an implementation (CustomerDAOImplOracle).
It was relatively straight forward for us to write SQL Server versions of the DAO's (the SQL syntax and jdbc libraries were of course different) and swap them over with minimal changes to our business logic (the services which use the DAO's).
So, CustomerDAOImplOracle was reimplemented at CustomerDAOImplSQLServer. And so on...
What we learn:
Interfaces provide good abstractiuon and allow for multiple implementations
The DAO layer allows us to "switch out" the database (or its client libraries) if necessary
Hiding implementation details of the database from the business logic reduces coupling and complexity
I've been trying to improve the separation of concerns when it comes to applications that access a database (via Hibernate).
On one of the applications I've been using the following approach:
Create services with business logic that have no connection/awareness of the database. They only communicate with GeneralDAO (and with other services);
A GeneralDAO responsible for CRUD/find operations, and with methods that involve more complex database queries.
The problems I see with this approach are:
GeneralDAO slowly becomes a God Object, when your application grows and require lots of specific database queries.
Sometimes the more specific Services become only proxies to the GeneralDAO, since the method is simple and only requires a database query. See example 1.
Example 1: Service is just a proxy
BookService manages things related to books in the Library application. Let's consider 2 methods:
archiveBook(Book)
findByIsbn(String isbn)
In archiveBook(Book) there might be considerable business logic involved - we might imagine this involves calls to:
distributionService.unbox(Book);
archivalBook.archive(Book);
librarianService.informNewBook(Book);
But findByIsbn(String isbn) is a lot more simple: it just needs to execute an SQL call to the database. So in this case I see two options:
Redirect the call to an object that can speak to the database to execute the query. For example generalDAO.findByIsbn(String isbn), that uses a db communication layer (in Hibernate it would use a sessionFactory or EntityManager) to execute the query.
Make that database layer available to the BookService, so that it executes the query itself
Questions/opinions (first number identifies the option above):
1.1. Isn't it strange to have 2 methods with the exact same signature, even if this is done to keep the BookService independent of the database layer (and ORM)?
1.2. How do you suggest avoiding The God anti-pattern? Would you suggest breaking the GeneralDAO into several DAOs depending on what the methods do? In this case, won't we risk needing to inject lots of DAOs into some Services, leading to a Service having too many objects injected into it?
2.1 What do you think of this alternative? Doesn't it break the "separation of concerns" by having the BookService be aware of objects at two different levels of abstraction (the DAO and the sessionFactory/EntityManager)?
3.1. Would you suggest any other approach/pattern/best practise?
Thanks!
1.2. How do you suggest avoiding The God anti-pattern? Would you suggest breaking the GeneralDAO into several DAOs depending on what
the methods do? In this case, won't we risk needing to inject lots of
DAOs into some Services, leading to a Service having too many objects
injected into it?
Generally, a DAO class should handle a specific entity.
If one of your entities require many kinds of queries, you could divide it again into two or more DAOs by grouping them by common concern (for example : reading, writing, selecting on agregates, etc...) as you said.
If you have too many queries and too many DAO, maybe, you should check if you don't write almost the same queries in several methods. It it the case, use specification or Criteria API to allow the client to custom queries by parameters. If the queries are really different, you have various processings. So, using multiple DAOs seems a suitable solution. It avoids increasing the complexity and the rise of god objects.
1.1. Isn't it strange to have 2 methods with the exact same signature, even if this is done to keep the BookService independent of the
database layer (and ORM)?
When you divide you app in logic layers, as you noticed, in some operations, some layers perform only delegation calls to the below layer. So in these cases, it is rather common to have method names which are the same. I would go further : it is a good practice to have the same name if it is just delegation call. Why do we create a variation in the conveyed behavior if they both address the same need?
2.1 What do you think of this alternative? Doesn't it break the "separation of concerns" by having the BookService be aware of objects
at two different levels of abstraction (the DAO and the
sessionFactory/EntityManager)?
BookService depends on DAOs but should not depend on sessionFactory/EntityManager which makes part of the DAO implementation.
BookService calls DAO which uses a sessionFactory/EntityManager.
If necessary, BookService may specify transactional details on itself or on its methods with #Transactional annotation.
3.1. Would you suggest any other approach/pattern/best practice?
As you use Spring, try to rely on the Sping JPA repository (less boiler plate to handle for common cases and extensible class)
Using specification or criteria patterns when you have several variants of some queries.
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 thinking about using the Open Session In View (OSIV) filter or interceptor that comes with Spring, as it seems like a convenient way for me as a developer. If that's what you recommend, do you recommend using a filter or an interceptor and why?
I'm also wondering how it will mix with HibernateTemplate and if I will lose the ability to mark methods as #Transactional(readOnly = true) etc and thus lose the ability to get some more fine grained transaction control?
Is there some kind of best practice for how to integrate this kind of solution with a three tier architecture using Hibernate and Spring (as I suppose my decision to use Wicket for presentation shouldn't matter much)?
If I use OSIV I will at least never run into lazy loading exceptions, on the other hand my transaction will live longer before being able to commit by being uncommitted in the view as well.
It's really a matter of personal taste.
Personally, I like to have transaction boundaries at the service layer. If you start thinking SOA, every call to a service should be independent. If your view layer has to call 2 different services (we could argue that this is already a code smell) then those 2 services should behave independently of each other, could have different transaction configurations, etc... Having no transactions open outside of the services also helps make sure that no modification occurs outside of a service.
OTOH you will have to think a bit more about what you do in your services (lazy loading, grouping functionalities in the same service method if they need a common transactionality, etc ...).
One pattern that can help reduce lazy-loading error is to use Value Object outside of the service layer. The services should always load all the data needed and copy it to VOs. You lose the direct mapping between your persistent objects and your view layer (meaning you have to write more code), but you might find that you gain in clarity ...
Edit: The decision will be based on trade offs, so I still think it is at least partly a matter of personal taste. Transaction at the service layer feels cleaner to me (more SOA-like, the logic is clearly restrained to the service layer, different calls are clearly separated, ...). The problem with that approach is LazyLoadingExceptions, which can be resolved by using VO. If VO are just a copy of your persistent objects, then yes, it is clearly a break of the DRY principle. If you use VO like you would use a database View, then VO are a simplification of you persistent objects. It will still be more code to write, but it will make your design clearer. It becomes especially useful if you need to plug some authorization scheme : if certain fields are visible only to certain roles, you can put the authorization at the service level and never return data that should not be viewed.
If I use OSIV I will at least never
run into lazy loading exceptions
that is not true, in fact its extremely easy to run into the infamous LazyInitializationException, just load an object, and try to read an attribute of it, after the view, depending on your configuration you WILL get the LIE