Single DAO & generic CRUD methods (JPA/Hibernate + Spring)
Asked Answered
M

5

49

Following my previous question, DAO and Service layers (JPA/Hibernate + Spring), I decided to use just a single DAO for my data layer (at least at the beginning) in an application using JPA/Hibernate, Spring and Wicket. The use of generic CRUD methods was proposed, but I'm not very sure how to implement this using JPA. Could you please give me an example or share a link regarding this?

Mauramauralia answered 8/10, 2010 at 7:42 Comment(0)
C
91

Here is an example interface:

public interface GenericDao<T, PK extends Serializable> {
    T create(T t);
    T read(PK id);
    T update(T t);
    void delete(T t);
}

And an implementation:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> {

    protected Class<T> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public GenericDaoJpaImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass()
             .getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass
             .getActualTypeArguments()[0];
    }

    @Override
    public T create(T t) {
        this.entityManager.persist(t);
        return t;
    }

    @Override
    public T read(PK id) {
        return this.entityManager.find(entityClass, id);
    }

    @Override
    public T update(T t) {
        return this.entityManager.merge(t);
    }

    @Override
    public void delete(T t) {
        t = this.entityManager.merge(t);
        this.entityManager.remove(t);
    }
}
Culpable answered 8/10, 2010 at 10:56 Comment(5)
How would this fit in with slsb's and pojo entities (representing the db tables) ?Godliman
Great answer. Just a few comments: I rather pass the Class as a parameter in the constructor method (instead of a unchecked cast); the parameter t in the delete method should not be reassigned and the class would preferably be abstract.Especially
I tried to follow this example but the ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); code is throwing java.lang.ClassCastException with the following message: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType Do anybody know how to fix this? Thanks anyway.Generable
Why there is no transactions? I mean entityManager.getTransaction().begin(); and entityManager.getTransaction().commit();.Reproachful
@Reproachful If using JTA you do not need to all those methods, in fact IIRC it will throw an exception if you try to call those methods in a JTA context.Ivories
G
15

Based on the article Don't repeat the DAO we used this kind of technique for many years. We always struggled with problems with our patterns after we realized that we made a big mistake.

By using an ORM tool such as Hibernate or JPA you will not have to think DAO and Service layer separately. You can use EntityManager from your service classes as you know the lifecycle of transactions and the logic of your entity classes there.

Do you save any minute if you call myDao.saveEntity instead of simply entityManager.saveEntity? No. You will have an unnecessary dao class that does nothing else but will be a wrapper around EntityManager. Do not afraid to write selects in your service classes with the help of EntityManager (or session in hibernate).

One more note: You should define the borders of your service layer and do not let programmers to return or wait for Entity classes. The UI or WS layer programmers should not know at all about entity classes only about DTO-s. Entity objects have lifecycles that most of the programmers do not know about. You will have really serious issues if you store an entity object in a session data and try to update it back to the database seconds or hours later. Well you may would not do it but a programmer of the UI who knows the parameter types and return types of your service layer only would do to save some lines of code.

Gian answered 1/11, 2012 at 19:48 Comment(1)
Annotated transaction management in EJB?! Though you probably need much more sophisticated DAO, which will not be generic anymore, but anyways. I still find this method can be useful in specific cases.Luellaluelle
F
5

I was looking for this same thing. I found what appears to be exactly that- the Spring-Data JPA project provided by SpringSource. This is a code port from Hades and has now (Early 2011) been swallowed by Spring and better integrated. It allows you to use a single dao (SimpleJpaRepository) with a static create, or extend the base JpaRepository class to create any object specific dao with ready made CRUD+ methods. Also allows grails like queries just by using params names as the name of the method- in the interface (no implementation required!) i.e. findByLastname(String lastName); Looks very promising- being part of Spring projects will certainly ensure some future for it too. I have begun implementing this in my upcoming project now.

Fumarole answered 10/3, 2011 at 15:24 Comment(0)
M
2

if you are looking for a third party implementation , you can check http://www.altuure.com/projects/yagdao/ . it is a nnotation based generic DAO framework which supports JPA and hibernate

Millford answered 3/11, 2010 at 10:35 Comment(0)
L
1

You may also have a look at http://codeblock.engio.net/data-persistence-and-the-dao-pattern/

The related code can be found on github https://github.com/bennidi/daoism

It has integration with Spring and configuration examples for Hibernate and EclipseLink

Lenhart answered 6/2, 2014 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.