Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: one DAO for all the entities or one for each entity?

First of all, sorry for my english.

Im making, for a friend, a desktop application with JPA(EclipseLink) that access a SQLite database.

I already created the database and the entities in Eclipse. But i also created a class called UniversalDAO which is an utility class used by all the entities to access and persist the database:

package model.DAO;

import java.util.ArrayList;

import javax.persistence.*;

import model.entities.Entities;


public class UniversalDAO {


    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("TheDatabase");
    private static EntityManager em = emf.createEntityManager();

    private UniversalDAO (){}


    public static void close(){
        em.close();
        emf.close();
    }

    public static Entities getOne(Class<? extends Entities> table, Object primaryKey) {

        return em.find(table, primaryKey);
    }

    public static ArrayList<Entities> getAll(Class<? extends Entities> table) {

        ArrayList<Entities> ret = new ArrayList<>();

        for(Object obj : em.createQuery("SELECT o FROM " + table.getName() + " o").getResultList())
            ret.add((Entities) obj);

        return ret;
    }

    public static ArrayList<Entities> getWithCondition(Class<? extends Entities> table, String condition) {

        ArrayList<Entities> ret = new ArrayList<>();

        for(Object obj : em.createQuery("SELECT o FROM " + table.getName() + " o WHERE " + condition).getResultList())
            ret.add((Entities) obj);

        return ret;
    }

    public static void insert(Entities row) {
        em.getTransaction().begin();

        em.persist(row);

        em.flush();

        em.getTransaction().commit();
    }

    public static void update(Entities row) {

        em.getTransaction().begin();

        em.merge(row);

        em.flush();

        em.getTransaction().commit();
    }

    public static void delete(Class<? extends Entities> table, Object primaryKey) {

        em.getTransaction().begin();

        Entities row = em.find(table, primaryKey);

        em.remove(row);

        em.flush();

        em.getTransaction().commit();
    }
}

To group all the entites and use them in this class i created an empty interface called Entities.

This is how one of the entities looks like:

package model.entities;

import java.util.ArrayList;

import javax.persistence.*;


@Entity
@Table(name="emails")
public class EntityEmail implements Entities {

    @Id
    @Column(name="id_email")
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int idEmail;

    @Column(name="email")
    private String email;

    @Column(name="description")
    private String description;

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="people_emails",
               joinColumns=@JoinColumn(name="id_email", referencedColumnName="id_email"),
               inverseJoinColumns=@JoinColumn(name="id_person", referencedColumnName="id_person"))
    private ArrayList<EntityPerson> people;

    public EntityEmail() {

    }   

    public int getIdEmail() {
        return this.idEmail;
    }
    public void setIdEmail(int idEmail) {
        this.idEmail = idEmail;
    }   

    public String getEmail() {
        return this.email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public ArrayList<EntityPerson> getPeople() {
        return people;
    }
    public void setPeople(ArrayList<EntityPerson> people) {
        this.people = people;
    }   
}

Like you can appreciate im not a professional and i still have a lot to learn. So, i was wondering if this approach is correct or if i should have one DAO for each entity.

like image 423
ivan0590 Avatar asked Sep 03 '25 05:09

ivan0590


1 Answers

It looks like you try to invent Generic DAO pattern. If so, you're essentially on the right way.

Generic DAO pattern works as follows:

  • Create a generic base class that all your DAOs will extend:

    public abstract class GenericDao<E, ID extends Serializable> {
        ...
        // Implement common operations that are relevant to all entities here:
        public E findById(ID id) { ... }
        public void save(E entity) { ... }
        // etc
        ...
    }
    
  • Create concrete DAO implementations by extending GenericDao:

    public class EntityEmailDao extends GenericDao<EntityEmail, Integer> {
        // This class may contain operations that are relevant to specific entity:
        public E findByEmail(String email) { ... }
    }
    
  • Since GenericDao is generic, you don't need to make your entities extend any common interface

There are plenty of exisiting implementations of this pattern around, take a look, for example, here.

like image 163
axtavt Avatar answered Sep 04 '25 19:09

axtavt