DAO and Service Levels (JPA / Hibernate + Spring)

I am developing a new application based on JPA / Hibernate, Spring and Wicket. The difference between the DAO and Service levels is not so clear to me. According to Wikipedia, DAO

an object that provides an abstract interface to some type of database or a storage mechanism that provides some specific operations without exposing database information.

I was wondering if the DAO might contain methods that really don't have much to do with data access, but is it easier to execute the query? For example, β€œget a list of all airlines that operate in a specific set of airports”? It seems to me that this is more of a service level method, but I'm not sure if using the JPA EntityManager at the service level is an example of good practice?

+61
java spring architecture jpa dao
Oct 07 '10 at 13:30
source share
5 answers

The DAO must provide access to one related data source and, depending on how complex your business model is, will return either full-fledged business objects or simple data objects. In any case, DAO methods should reflect the database somewhat closely.

A service can provide a higher-level interface that not only processes your business objects, but also allows you to access them in the first place. If I get a business object from the Service, this object can be created from different databases (and different DAOs), it can be decorated with information made from an HTTP request. It can have a specific business logic that converts multiple data objects into a single, reliable business object.

I generally create a DAO, thinking that it will be used by anyone who is going to use this database or a set of data related to the business, this is literally the lowest level of code, except for triggers, functions and stored procedures in the database.

Answers to specific questions:

I was wondering if the DAOs can contain methods that actually don't have much to do with data access, but is the easiest way to execute the query?

in most cases not, you will need your more complex business logic at the service level, collecting data from individual requests. However, if you are concerned about processing speed, the service level can delegate the DAO action, even if it violates the beauty of the model, much like a C ++ programmer can write assembler code to speed up certain actions.

It seems to me that I am more of a service level method, but I am not sure if using the JPA EntityManager in the service level is an example of good practice?

If you intend to use the entity manager in your service, then think of the entity manager as your DAO, because that is exactly what it is. If you need to remove redundant query building, do not do this in your service class, retrieve it in the class that uses the entity manager, and do it DAO. If your use case is really simple, you can completely skip the service level and use the entity manager or DAO in the controllers, because all your services will transfer calls to getAirplaneById() in the DAO findAirplaneById()

UPDATE. To clarify the discussion below, using an entity manager in a service is probably not the best solution in most situations, where there is also a DAO level for various reasons highlighted in the comments. But, in my opinion, this would be quite reasonable:

  • The service must interact with different data sets.
  • At least one dataset already has a DAO
  • The service class is in a module that requires some persistence, which is simple enough to not guarantee its own DAO

Example.

 //some system that contains all our customers information class PersonDao { findPersonBySSN( long ssn ) } //some other system where we store pets class PetDao { findPetsByAreaCode() findCatByFullName() } //some web portal your building has this service class OurPortalPetLostAndFoundService { notifyOfLocalLostPets( Person p ) { Location l = ourPortalEntityManager.findSingle( PortalUser.class, p.getSSN() ) .getOptions().getLocation(); ... use other DAO to get contact information and pets... } } 
+51
Oct 07 '10 at 13:55
source share

One thing is clear: if you use the EntityManager at the service level, you do not need the dao level (only one level should know the implementation details). In addition, there are different opinions:

  • Some say that EntityManager provides all the necessary dao features, so they embed EntityManager in the service layer.
  • Others have a traditional dao level supported by interfaces (therefore, the service layer is not tied to implementation details).

The second approach is more elegant when it comes to sharing problems, and also facilitates the transition from one persistence technology to another (you just need to re-implement the dao interfaces with the new technology), but if you know that nothing will change, the first is simpler.

I would say if you have a small project, use JPA at the service level, but in a large project use a dedicated DAO layer.

+14
Oct 07 '10 at 13:36
source share
+5
Sep 26 '11 at 22:53
source share

Traditionally, you should write interfaces that define a contract between your service level and data level. Then you write implementations, and these are your DAOs.

Back to your example. Assuming that the relationship between an airport and an airline is a lot for many with a table containing airport_id and airline_id, you might have an interface;

 public interface AirportDAO { public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports); } 

.. and you can provide an implementation of Hibernate,

 public class HibernateAirportDAO implements AirportDAO { public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports) { //implementation here using EntityManager. } } 

You can also see if there is a list in your airline organization and determine the relationship with the @ManyToMany JPA annotation. This would eliminate the need to have this particular DAO method at all.

You can also see the Abstract Factory template for writing DAO factories. For example:

 public abstract class DAOFactory { private static HibernateDAOFactory hdf = new HibernateDAOFactory(); public abstract AirportDAO getAirlineDAO(); public static DAOFactory getFactory() { //return a concrete implementation here, which implementation you //return might depend on some application configuration settings. } } public class HibernateDAOFactory extends DAOFactory { private static EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("myPersistenceUnit"); public static EntityManager getEM() { return emFactory.createEntityManager(); } public AirportDAO getAirportDAO() { return new HibernateAirportDAO(); } } 

This template allows your HibernateDAOFactory to have one EMF and deliver separate DAO instances with EM. If you don't want to go a long route, then Spring is great for handling DAO instances for you with dependency injection.

Edit: Clarified a few assumptions.

+4
Oct 07 2018-10-10
source share

Tao is an object of access to data. It saves / updates / selects objects in the database. An entity manager object is used for this (at least in open jpa). You can also run a query with this entity manager. This is not sql, but JPQL (Java Conservation Request Language).

A simple example:

 emf = Persistence.createEntityManagerFactory("localDB"); em = emf.createEntityManager(); Query q = em.createQuery("select u from Users as u where u.username = :username", Users.class); q.setParameter("username", username); List<Users> results = q.getResultList(); em.close(); emf.close(); 
0
Oct 07 '10 at 13:36
source share



All Articles