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
Related
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'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.
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.
I need some advice on designing an "Integration Tier" of an N-Tiered system in Java. This tier is responsible for persisting and retrieving data for the "Business Tier" (located on a separate server). I'm new to J2EE and I've read a few books and blogs. The alphabet soup of technology acronyms is confusing me so I have a handful of questions.
First, what I have so far: I'm using JPA (via Hibernate) for persisting and retrieving data to a database. I made my data access objects EJBs and plan on deploying to an application server (JBoss) which makes transactions easier (they're at the function level of my DAOs) and I don't have to worry about getting a handle to an EntityManager (dependency injection). Here's an example of what things look like:
#Entity
class A{
#Id
Long id;
#OneToMany
List<B> setOfBs = new ArrayList<B>;
}
#Entity
class B{
#Id
Long id;
}
#Remote
public interface ADAO{
public A getAById(Long id);
}
#Stateless
class ADAOImpl implements ADAO{
#PersistenceContext
EntityManager em;
public A getAById(Long id){ ... }
}
My question: How should the Business Tier exchange data with the Integration Tier. I've read up on RESTful services, and they seem simple enough. My concern is performance when the frequency of gets and sets increases (HTTP communication doesn't seem particularly fast). Another option is RMI. My DAOs are already EJBs. Could I just have the Business Tier access them directly (via JNDI)? If so, what happens if the #OneToMany link in the example above are lazily loaded?
For example if the Business Tier does something like the following:
Context context = new InitialContext(propertiesForIntegrationTierLookup);
ADAOImpl aDao = (ADAOImpl) context.lookup("something");
A myA = aDao.getAById(0);
int numberOfBs = myA.setOfBs.size();
If the setOfBs list is loaded lazily, when the Business Tier (on a separate server) accesses the list, is the size correct? Does the list somehow get loaded correctly through the magic of EJBs? If not (which I expect), what's the solution?
Sorry for the long post. Like I said I'm new to J2EE and I've read enough to get the general idea, but I need help on fitting the pieces together.
When you call size() on lazy collection, it gets initialized, so you'll always get correct size no matter which interface you're using - Remote or Local.
Another situation is when you're trying to use JPA classes as data transfer objects (DTO) and request them via Remote interface. I don't remember any lazy initialization issues here, cause prior to transmission all objects have to be serialized (with lazy collections initialized) on server side. As a result, the whole object graph is passed over network, which might cause serious cpu and network overheads. In addition, for deserialization to be possible, you will have to share JPA classes with remote app. And that's where and how 'EJB magic' ends :)
So, once remote calls are possible, I'd suggest to start thinking of data transfer strategy and non-JPA data transfer objects as additional data layer. In my case, I've annotated DTO classes for XML binding (JAXB) and reused them in web-services.
Short answer: If you are using an "Integration Layer" approach, the things you should be integrating should be loosely coupled services, following SOA principles.
This means you should not be allowing remote calls to methods on entities that could be making calls to the framework under the lid on another server. If you do this, you are really building a tightly coupled distributed application and you will have to worry about the lazy loading problems and the scope of the persistence context. If you want that, you might like to consider extended persistence contexts http://docs.jboss.org/ejb3/docs/tutorial/extended_pc/extended.html.
You have talked about a "business tier", but JPA does not provide a business tier. It provides entities and allows CRUD operations, but these are typically not business operations. a "RegisterUser" operation is not simply a question of persisting a "User" entity. Your DAO layer may offer a higher level of operation, but DAOs are typically used to put a thin layer over the database, but it is still very data centric.
A better approach is to define business service type operations and make those the services that you expose. You might want another layer on top of your DAO or you might want to have one layer (convert your DAO layer).
You business layer should call flush and handle any JPA exceptions and hide all of that from the caller.
The issue of how to transfer your data remains. In many cases the parameters of your business service requests will be similar to your JPA entities, but I think you will notice that often there are sufficient differences that you want to define new DTOs. For example, a "RegisterUser" business operation might update both the "User" and "EmailAddresses" table. The User table might include a "createdDate" property which is not part of the "RegisterUser" operation, but is set to the current date.
For creating DTOs, you might like to look at Project Lombok.
To copy the DTO to the Entity, you can use Apache Commons BeanUtils (e.g., PropertyUtils.copyProperties) to do a lot of the leg work, which works if the property names are the same.
Personally, I don't see the point in XML in this case, unless you want to totally decouple your implementations.