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
Related
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 am using Spring with Hibernate.
My hibernate model I am using is 'NodeInstanceLog' which is the object that is retrieved from the database.
My current structure:
At the moment, NodeInstanceLogDAO is handling the retrieving of the data from the database.
The other option would be to change my structure to make it so NodeInstanceLog is fetchable and make it manage itself. Ie being able to retrieve its data from the database.
What are the advantages and disadvantages of each?
It's a matter of separation of concern. A model represents a part of your problem domain, while the DAO is concerned with getting data in and out of a datastore. Two completely different problems, requiring dedicated classes.
In general, the more you split up responsibilities, the more modular your code base is with many advantages:
* our brains tend to be good in focussing on one small thing at a time, so reading (=maintaining) your code will be easier, as it's more structured.
* testing is easier when different responsibilities are separated in small classes: a test can manipulate one simple focussed class at a time
* reuse is more likely: if you want to do something else with a model instance that has nothing to do with DAO, that DAO code in there would be dragged into the other thing you wanna do for nothing
Anyway, there is probably a lot more to say. Try googling "separation of concern", "loose coupling", ... But take it from me: splitting responsibilities is the way to go :)
In plain java, using DAOs / Repositories is usually better as otherwise your objects will need to have quite a lot of database logic. Database logic is NOT business logice, and your model should only represent the business model.
Play is a framework that can weave a lot of the persistence logic automagically into your classes (using aspects), in this way your model class has methods to query the DB, but it doesn't have the logic.
If you're learning this stuff, I would suggest you to implement both and experience what pains each solution creates (e.g. how do you deal with transactions? from where do you take a DB Connection?)
I also suggest you to read the book Patterns of Enterprise Application Architecture, in particular Active Record (having the logic weaved into your class) and Unit of Work (Hibernate)
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.
I have a project implemented in a (flawed) 3-tier architecture. My job is making it more generic so that it would be easy to add a new database into the project.
Concrete: there is a databaseFacade for an SQL database and i have to make it more generic so we can add multiple databases very easy. In this case writing it to a CSV file.
My idea in the database layer was to make a interface where all the methods are defined. Then having the database facade (depending which you want to use) implementing this interface so that it becomes more generic.
Then i have some kind of DBmanager class. This DBmanager class will read out a config file so he knows what database to use. Based on this info he will create an instance of the interface and return this to the application layer.
However this is where I don't know if i'm correct. The application layer now has a DBmanager class (where everything is correctly encapsulated only 1 method is public for returning the facade) and after that the DBfacade.
Any thoughts about the correctness of this? Since I'm having doubts.
I've seen a PHP system (Moodle) use almost exactly this pattern and it works fine. All that happens is that the DB type is specified as a config variable and the concrete DB access class is instantiated as the global DB manager object, providing the facade methods e.g. get_records(), which returns a standardised array of row objects. Arguable whether you would call this facade or adapter, but that's hardly a worry.
I'd say go for it with your current plan. You seem to have decoupled the layers properly and understood the purpose of the patterns. Also, the way your low level (DB) and high level (application controller) components both depend on a single DB facade interface in the middle is a good example of dependency inversion, so bonus points for that! :)
This is the correct approach. One minor quibble is that your DBManager actually follows the Factory pattern, and so should be called DatabaseFacadeFactory, assuming that your facade class is called DatabaseFacade.
As you become more comfortable with Java, check out Spring. It provides a lot of tools and techniques that automatically handle situations such as this, and remove the need for much of the boilerplate code. For more information, see dependency-injection.
To me, it seems legit. I'm not an expert in software architecture yet, but your description describes similar concept in comparison to how JDBC was designed.
I understand separating the data layer objects (DAOs) in their own layer that abstracts the data access logic and data source specifics from service and business layers as outlined in DAO and Service layers (JPA/Hibernate + Spring) and other questions. I have experience creating these layers, but I've always used either raw JDBC or similar lower level ways of interfacing with the DB (such as Spring's SimpleJDBC), and am new to Hibernate.
My question comes in that in raw JDBC or other ways where you are actually dealing with a result set (or a thin wrapper around it) at the data access layer, the resulting POJOs where you stick your data are extremely clean and know nothing about where the data came from, and I've never worried about returning these to the service layer and beyond. However it appears that with Hibernate, you have a lot of your Hibernate / data structure specific logic right in the POJO annotations (things like 1 to many mappings, lazy loading preferences, etc). I feel uncomfortable returning them (or Collections of them) from my DAOs and up to my service layer and am tempted to have all the POJOs implement interfaces that I pass back instead. Is this good practice, or over complicating?
Annotations have one drawback of coupling some framework knowledge with Java objects. That's the price you pay for not having separate metadata definitions. POJOs still remain POJOs, though, and from practical standpoint I see no good reason to complicate design just because of annotations.
Lets think, if you would use XML mappings, would you even have that concern? Most likely - not. So pay the penalty and move on; and in unlikely case if you will be changing your persistence framework - you will go ahead and remove those annotations. In all cases they should have no side effects on your code outside of your DAO layer.
Just my 2 cents...
Both ;) I'm pretty ambivalent--I prefer interfaces, it's just easier to mock, use across non-Hibernate systems, etc. but in my case I've usually needed to provide an external API with datatypes, so it's almost always made sense. That, and I generate the interfaces automatically, so I don't have to actually do anything.
For isolated systems with no external API requirements, or if you never need the types outside of Hibernate, I'm not convinced it really matters all that much, although the purists will have my head on a pike for saying so (and they're arguably correct).