0

For example: i have User.class and Post.Class I want to get all rows from this tables with hibernate. It is done with

TypedQuery<Post> query = SessionFactory.getCurrentSession().createQuery("from Post");

Also i have dao layer, UserDao and PostDao. and i have abstract class CrudDao with methods like:

public abstract class CrudDao<T> {


    @Transactional
    public void save(T entity) {
        SessionFactory.getCurrentSession().save(entity);
    }
}

So my user and post dao just extend this crudDao and i don't need to write save method for them. When i want to get all rows i need to write "from MyEntitie". But i want to make this method also abstract, so i don't need to write it multiple times for each dao. But i can't write "from T" in abstract method.

I also tried to do like this:

List<T> getAll(Class<T> type){
    CriteriaQuery<T> criteria = builder.createQuery(type);
    criteria.from(type);
    return 
  SessionFactory.getCurrentSession().createQuery(criteria).getResultList();
}

So in my service i call my dao like this:

PostDao.getAll(Post.class);

And i was told that my service shouldn't know about my entity and my dao call in service should be PostDao.getAll(); And if i do like this ^ i need to write getAll method in every dao and it looks like a lot of copypasted code.

Can yoy give me some advice on how to do it or how you do it in your projects?

Ars
  • 591
  • 1
  • 4
  • 19
  • 1
    See [this question](https://stackoverflow.com/questions/9721383/hibernate-crud-generic-dao) and if you don't like/understand/want it, then google for a *generic dao*. – deHaar Jun 18 '19 at 11:54

2 Answers2

0

What i learned from deHaar reply: You can create abstract methods with generic dao and call generic class if you create a variable of this generic type/ For example my generic dao:

public abstract class CrudDao<T> {

    private Class<T> type;

    public CrudDao(Class<T> type){
        this.type = type;
    }

    @Transactional
    public T getById(,int postId) {
    return sessionFactory.getCurrentSession().get(type, postId);
}
}

So you need only to write a constructor that calls superclass constructor in your child Dao's that extend generic dao. Like :

public class PostCommentDao extends CrudDao<PostComment> {

    public PostCommentDao(){
        super(PostComment.class);
    }
}

And now everything works from generic dao!

As Tanos said: small price to pay for salvation.

Ars
  • 591
  • 1
  • 4
  • 19
0

In my opinion, generic DAO is an antipattern. Spring provides you with excellent three-tier architecture made of @Controller (for mvc and rest), @Service (for functionality reusability) and @Repository (for data access). It's okay to have a little bit more code just to leave it with a single responsibility.

Alan Sereb
  • 2,358
  • 2
  • 17
  • 31
  • "a little bit more" - means having CRUD dao opeartions copypasted in every DAO? Are you serious? – Ars Jun 20 '19 at 07:58
  • Yes. It is incomparable with the general solution. Generic approach will always have awkward code resolving business logic exceptions. – Alan Sereb Jun 20 '19 at 15:32