New to Java - What's JPA and DAO?

17,182

Solution 1

DAO stands for "Data Access Object". It abstracts the concept of "getting something from a datastore". Your DAO objects can be implemented with JDBC calls, JPA calls or whatever. Maybe it calls some remote webservice. Having a DAO over JPA seems redundant and it does add a layer, but I think it is worth it.

For example, you might have a use case of "display users that have green eyes".

with straight JPA:

List<User> users = entityManager.createQuery("select u  from User u where u.EyeColor = 'green'"");

with a DAO you'd have:

List<User> users = dao.UsersWithEyeColor("green");

The DAO here has a couple of advantages:

  1. It is easier to read.
  2. It doesn't expose your database structure to the rest of the application
  3. It would be much easier for unit testing. The class that is getting users with green eyes only needs to create a "Mock" dao. This is easier than mocking JPA.

These are just a few arguments for using a DAO. For a very simple, small application it might be too much overhead. But for anything that will become larger and need to be maintained for many years I think it is worth it.

Solution 2

DAO (Data Access Object) is basically a pattern for programming, to use this, you must create a class that will create an object that provides an abstract interface to some type of persistence unit (db, file system. xml, etc).Why is it useful? Because it provides some specific data operations without exposing details of the database.

An basic example of DAO:

import java.util.List;


public abstract class DAOFactory {

    public static final int MYSQL_JDBC = 1;
    public static final int MYSQL_JPA = 2;
    public static final int MYSQL_HIBERNATE = 3;

    public abstract List<UserDTO> listAllUsers();

    public static DAOFactory getDAOFactory(int whichFactory) {
        switch (whichFactory) {
        case MYSQL_JDBC : return new MySqlJDBCDaoFactory();
        case MYSQL_JPA: return new MySqlJpaDaoFactory();
        case MYSQL_HIBERNATE: return new MySqlHibernateDaoFactory();
        default: return null;
        }
    }

}

Then you have to create an specific factory for each type of persistence you will manage in your application, and that specific factory must implement the methods you use for persistence, for example listAllUsers();

For example, for MySQL JPA:

public class MySqlJpaDaoFactory extends DAOFactory {

    @Override
    public List<UserDTO> listAllUsers() {
      // Here I implement specific functionality to retrieve data using JPA Framework
        //EntityManagerFactory emf = ...
        //EntityManager em = ...
        //List<UserDTO> list = em.get...();
        //return list;
        return null;
    }

}

For MySQL JDBC you have to do other process:

public class MySqlJDBCDaoFactory extends DAOFactory {

    @Override
    public List<UserDTO> listAllUsers() {
        //Connection = DriverManager ...
        //PreparedStatement ps = connection.prepareStatement("select * from ...");
        //ResultSet = ps.executeQuery()
        // and so on...
        return null;
    }

}

Then you invoke your factory this way:

DAOFactory myfactory = DAOFactory.getDAOFactory(DAOFactory.MYSQL_JDBC);
List<UserDTO> list = myfactory.listAllUsers();

And if you can see no matter if you change your database framework or persistence mode, you don't have to re-invent the wheel, just change a parameter and you will get the implementation for persistence you want, just based in a parameter.

Hope it could help you to understand the pattern, I don't use EJB, and if you're using DAO I don't think it is still necessary to implement EJB's.

Best regards

Share:
17,182
mimipc
Author by

mimipc

Updated on June 04, 2022

Comments

  • mimipc
    mimipc almost 2 years

    I'm new to Java and i'm trying to make a web project with servlets. I'd like to query my database but I think I don't understand everything about JPA and DAO.

    I've been taught to do things this way :

    • Create class com.package.entity.User (generated from my database)
    • Create interface com.package.dao.UserDao
    • Create class com.package.dao.jpa.JpaUserDao implementing UserDao
    • Create EJB com.package.service.UserService with methods like public List<User> findAll()

    I've heard there's no need to create a DAO interface with JPA but I'm completely lost and I don't understand at all what I should do or what an EJB is. I simply want to find all the users in my database and display their names following Java's good practices.

    It's allready OK for my servlets and JSPs.

    What would you recommend ?

  • artaxerxe
    artaxerxe about 10 years
    Your queries will return green eyed users, not blue eyed, as you intended initially. :)
  • Johannes Jander
    Johannes Jander over 7 years
    That seems completely over-engineered for the normal use-case where you either get your data via JDBC or via JPA2, but you don't change the access methodology nilly-willy. Forget the Factories, just instantiate your DAOs.
  • Karen Goh
    Karen Goh almost 7 years
    @Marcelo, can i know why JDBC is still needed when JPA is being used? Currently, I am also doing something like that but I am quite confused whether I should mixed JDBC with JPA. Hope to hear from you. Tks.
  • Marcelo Tataje
    Marcelo Tataje almost 7 years
    Hi @KarenGoh. If you've decided to use a persistence framework such JPA, then I do not see the reason why you should mix JDBC with it. In this particular example, I just tried to show how can you handle different type of persistence "managers" based on an application I worked with in my previous job. It started with this pattern (DAO) using JDBC in 2004, later it was to migrated to Pure Hibernate on 2009 and then I migrated to JPA (+Eclipselink) on 2013. The example was made just to show how can we change the persistence mode from one type to another in an easy way with this pattern.
  • Marcelo Tataje
    Marcelo Tataje almost 7 years
    You can go ahead just with JPA, is an easy way to manage your entities through the ORM specification, if you need native queries then JPA provides "createNativeQuery" method in which you can provide a pure SQL instruction to query the database.
  • Karen Goh
    Karen Goh almost 7 years
    @Marcelo, the thing is that I have started out with JDBC and DAO. Then, I find it very difficult to do the insertion of data into the link table so basically I am using JPA to do that. However, I find my code rather messy now. Any idea how I could do it without re-do my project?
  • Marcelo Tataje
    Marcelo Tataje almost 7 years
    Are you using DAO along with Factory like in the example above or just DAO without any kind of factory implementation? You can make a refactor to not implement the whole thing again. If you are using JDBC, then you should have implemented things such PreparedStatement and Resultset components. I'd say that you can get rid of the JDBC by replacing all that stuff by calling your entityManager object and try to use your entities model to get list of results (or individual result depending on the case). If the query you need is too complex, then you can use the "createNativeQuery".
  • Marcelo Tataje
    Marcelo Tataje almost 7 years
    If you, however, want to re-do your project, then start using JPA for all the stuff at the very beginning for everything. Just make sure all the relationships of your data model are well-defined.