Search code examples
springhibernatejpaormspring-orm

Implementation of DAO vs JPA


I would like to know the difference between JPA and Hibernate. I have read the very interesting question posted by @Anthony with interest but still I do not understand the full picture.

I have implemented my application in Spring MVC and Hibernate (see below). My DAOs are an implementation of services which have been built using HQL queries.

@Service("messagesService")
public class MessagesService
{
    private MessagesDAO messagesDAO;

    @Autowired
    public void setMessagesDAO(MessagesDAO messagesDAO)
    {
        this.messagesDAO = messagesDAO;
    }

    public List<Message> getAllMessages()
    {
        return messagesDAO.getAllMessages();
    }
...
--------
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
@Component("messagesDAO")
public class MessagesDAO
{
    @Autowired
    private SessionFactory sessionFactory;

    public Session session()
    {
        return sessionFactory.getCurrentSession();
    }

    @SuppressWarnings("unchecked")
    public List<Message> getAllMessages()
    {
        Criteria crit = session().createCriteria(Message.class);
        crit.createAlias("usernameSender", "u").add(Restrictions.eq("u.enabled",true));
        return crit.list();
    }
    ...

I really like the statement "JPA is the dance, Hibernate is the dancer." but in my specific case I do not fully get why my example is not JPA. MessageService is the dance and MessagesDAO the dancer(Implementation).

As @Kevin states:

Think of JPA as the guidelines that must be followed or an interface, while Hibernate's JPA implementation is code that meets the API as defined by the JPA specification and provides the under the hood functionality.

I know I have not defined my service as an interface but this still lets me think that my code complies with the JPA specification requirements.

Now a concern arises

What is the difference between my example and the following from the pet clinic example

package org.springframework.samples.petclinic.repository;

import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType;


public interface PetRepository {

    List<PetType> findPetTypes() throws DataAccessException;

-------
@Repository
public class JpaPetRepositoryImpl implements PetRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    @SuppressWarnings("unchecked")
    public List<PetType> findPetTypes() {
        return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList();
    }

The reason why I am asking all this questions is because I am using MySql in my application and I am thinking to change it in the future.

Therefore, I am trying to build my implementation layer to avoid any problem later on.

I was looking at nosql options and I discovered spring data jpa for the integration layer. I then started to learn a bit more about JPA and DAOs and the questions above suddenly arose

If I implement spring data jpa, can I use MySql for the moment and change it later to another database (Cassandra, MongoDb)?

What is the difference between Spring data JPA and Spring Data Mongodb (The first is the specification and the second one the implementation?)

Thank you for your help


Solution

  • To keep the terminology: In your DAO you can't change your dancing partner.

    Why? Because you are referencing Hibernate explicitly. If you would like to change the dancer some day you would have to change your whole implementation. Thats why you usually use only classes of the dance - JPA or Spring Data in your case.