May Service annotated classes contain SQL/HQL in spring framework? - java

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.

Related

Best practices to separate concerns when accessing database

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.

Extra actions in a setter of a hibernate entity

I'm working on a legacy project with hibernate. Occasionally I find code where the developers wrote extra code in the set methods of entity objects. I'm wondering if this is an accepted practice ? Shouldn't hibernate entity objects just be pojo classes with extra annotations and maybe a few #Transient helper methods ?
If you want to do extra actions isn't that the responsibility of the service/dao working with the entity ?
What is the best practice ? Does anyone know of a blog or recognized article explaining this ?
IMHO, both approaches are correct. They both have its pros and cons. This is related to the everlasting Anemic model vs DDD (Domain-driven design) war.
Regarding Hibernate, it is quite flexible. It lets you took either approach you want. Performance and correctness of the solution don't depend on the decision you take, but on the correctness of the queries, database indexes, fetching strategies for entities, chosen algorithms, I/O handling, concurrency implementation, transaction management, etc.
If you go by DDD, the entities would be part of the business layer, while Hibernate itself (Session, SessionFactory and the whole ORM) would be part of the persistence layer. In this case, the entities would contain annotations related to persistence, which would be just hints for the ORM.
You should also be careful with transaction management. This is better accomplished outside of the entities. (Actually, one main advantage of the anemic model is that transaction management is very easy, because you wrap every service method of your business layer inside a transactional unit).
As you've mentioned you have a mix of both "ideologies", maybe you could use that fact as an advantage: let service methods delegate the logic to domain entities, but keep transaction management in your business services.

Using DAOs with composite Objects

I am trying to rewrite a bunch of DAOs here is the setting:
only plain JDBC (no JPA, ORM whatsoever)
no interfaces used
lots of checks before inserting an object
Business objects are strongly linked
My main question is:
How do I persist/retrieve a business object that is composed of multiple other objects?
e.g. does my CustomerDAO know the AddressDAO and retrieve the csutomers adresses from there?
only plain JDBC (no JPA, ORM whatsoever)
Business objects are strongly linked
Not sure why you don't want to use JPA while you want your business objects to be linked, but at least you should use Spring JDBC template that would relieve you from some boilerplate code.
Regarding the other constraints, I would do it as follows:
I would still employ interfaces to define the DAO methods and implement them in a Spring JDBC template backed DAOImpl. Use the DAO everywhere and inject the DAOImpl.
My DAOs will be simply one-to-one mapping to the underlying tables and each DAO wouldn't know about the existence of other DAOs.
My Manager layer will have all the business logic that runs validation checks and prepares the set of objects that need to be persisted, calls the appropriate DAO and appropriate method (CREATE/UPDATE/DELETE) to persist the objects.
Again, the Manager layer will follow the interface-based implementation and the view layer would have manager types injected with the ManagerImpls.
My two cents!
You may Consider Using JOOQ. It is not JPA, but it may easily be used as an alternative solution. It is lightweight enough. It also provides provides a reverse engineer tool, where it builds your Database entities as DAO objects.
I have embed JOOQ in a relevant situation, where the application was fairly engineered designed. I didn't use its DAO functionality, rather than using it as a higher layer to avoid messing with JDBC Layer.
Cheers!
Composite entities are a layer above DAO's. If you want to remove ALL coupling, domain objects persisted by DAOs should be flat without relationships. See Core J2EE patterns CompositeEntity.
Also, it's a good idea not to introduce coupling inbetween the DAO's by putting finders for one in the other. E.g.:
AddressDAO.findForCustomerId(id);
is inferior to using a third DAO to manage the relationship. I.E:
CustomerAddressRelDAO.findAddressForCustomer(id);
If you use a relationship DAO neither address nor customer are dependent on (or aware of) each other.

Hibernate (best)most common structure

I have a POJO class with hibernate annotations for each table in database. Also have one HibernateUtility for my database, which creates SessionFactory.
Should I create a manager per DB table or manager per DB?
Under manager I mean a class, which does all the transactions, CRUD.
Which gives me the best performance?
It's usually helpful to have a DAO per table. You don't need to write a lot of code, as you can use a generic dao.
Performance wise: remember that you're using hibernate, which down't have performance as one of its pillars, but hibernate usually brings down development time. If you need performance try using myBatis or just plain jdbc.
Performance has nothing to do with the number of classes you have.
A manager per DB table is too many: business use-cases typically involve more than one table.
A manager for the whole database is too few: having all the business logic of an application in one class is not maintainable.
An application typically has groups of use-cases: user management, notifications management, etc. I would use these as a way to split the logic into classes.
Also, note that business logic (which is what I assumed would be in your manager classes) should be separated from data access logic (DAOs, repositories). The CRUD is typically the responsibility of the DAO, whild the business logic and transaction demarcation is done in the service (manager) layer.
I prefer to have a DAO class for each table in the DB. I actually have an abstract DAO object which does all the usual CRUD operations and then I'll override or add additional query methods as they are needed. I wouldn't be able to re-use my CRUD logic if it was all in one DAO.
Actually, I'm surprised there is not a standard abstract CRUD implementation out there that everybody uses - it's trivial to write (maybe there is a well maintained one?). My generic DAO also has convenience methods for obtaining the EntityManagerFactory - useful in a Java SE environment where these sorts of things are not injected.

What is DAO and Service layer exactly in Spring framework?

What is DAO and Service layer exactly in Spring framework?
I am looking for theoretical answer.
There is no distinction as far as Spring is concerned. By convention you can mark DAO classes with #Repository and services with #Service. Also the former does some persistence layer exception translation.
Since you are asking theoretically: DAO should perform raw database operations and translate them to some higher level constructs (objects, collections). Services should call DAOs and perform business operations. Typically transactions demarcation is performed on service layer to span several DAO calls.
Finally DAO should abstract business logic from persistence details, ideally allowing to switch persistence layer without business logic (services) changes. This is hardly ever possible due to leaking abstraction of persistence providers (e.g. lazy loading).
DAO - data access object, are object to handle connection to your data storage (typicaly database). You have here your queries and DAO provides data to your services.
Services should contain all your logic. If you have logic separete you can theoretically change your UI layer or DAO layer without you affected it.
It gives decoupling benefits. When source of data changes the way you process data in Service for all service users (mobile client, web-client) does not change. But you need to change the way you extract data from data source.
DAO(Data Access Object) is a design pattern, which consists on creating for each table on your database a class,it provides a technique for separating object persistence and data access logic

Categories