1

At this moment I start work on small web application based on MVC. Now I try implement main classes for Model layout using DAO pattern.

So, first of all I create two entity classes (for example): Author and Book:

package myProject.model.entity;

import java.io.Serializable;

    public class Author implements Serializable {

        private static final long serialVersionUID = 7177014660621405534L;

        private long id;
        private String firstName;
        private String lastName;

        public Author() {       
        }
    // getter and setter methods here

    }

and Book class:

  package myProject.model.entity;

    import java.io.Serializable;

        public class Book implements Serializable {

            private static final long serialVersionUID = 7177014660621405534L;

            private long id;
            private String title;
            private String description;

            public Book() {     
            }
        // getter and setter methods here

        }

On next step, I see, that classes Book and Author both have getId() and setId(). so, I create interface Persistent for my Entity classes:

 package myProject.model.entity;

        public interface Persistent {

                public long getId();
                public void setId(long id); 


        }

So, first my question:

It is correct implementation for model package?

On the next step, I start implement classes for package dao.

package myProject.model.dao;

import java.util.List;

import myProject.model.entity.Persistent;

public interface Dao {

    Persistent get(long id);

    void save(Persistent persistent);

    void delete(long id);
}

Next step: create interfaces AuthorDao and BookDao, that extend base dao interface Dao

But both interfaces: AuthorDao and BookDao - at this moment empty. What do you think - it in normal, that interfaces empty? It is my second question.

And on the last step I create package model.dao.hibernate and add to the package to class AuthorDaoHibernate and BookDaoHibernate - both class implements AuthorDao and BookDao interfaces.

And My main question now:

my interface Dao work with objects type Persistent and I dont use Generics. And all ok and nice.

What do you thinks - what benefits I have, if I re-work Dao interface wit Generics:

package myProject.model.dao;

import java.util.List;

import myProject.model.entity.Persistent;

public interface Dao<Persistent> {

    T get(long id);

    List<T> getAll();

    void save(T persistent);

    void delete(long id);
}

My Dao classes work only with persistent entities - no any other object type...

Do you really any reasons in me case use Generics?

user471011
  • 7,104
  • 17
  • 69
  • 97

3 Answers3

2

Generics can greatly improve code readability and reduce errors that could come from wrong casting.

We're using something similar to what you described (note that there are interfaces and implementations needed).

Here's a basic example (I'll leave the getters and setters out for brevitiy):

@MappedSuperClass
class BaseEntity {
  @Id
  private int id;
}

@Entity
class UserEnity extends BaseEntity {
  //user stuff like name
}

class BaseDAO<T extends BaseEntity> {
  public T findById(int id) { 
    ... 
  }
  //other generic CRUD methods
}

@Stateless
class UserDAO extends BaseDAO<UserEntity> {
  //additional user specific methods
}

Using UserDAO would then be like this:

 UserDAO userDao; //some injection or lookup

 //no explicit cast needed here, thanks to generics
 UserEntity user = userDao.findById(userId);

 //compiler error due to the generic parameter being UserEntity and AnotherEntity doesn't extend that
 AnotherEntity a = userDao.findById(someId);
Thomas
  • 87,414
  • 12
  • 119
  • 157
  • BaseEntity - must be abstract or no? – user471011 Jan 24 '12 at 11:52
  • @user471011 no, it doesn't need to be abstract, it's just not annotated as being an entity and you can't persist a plain `BaseEntity` instance. It would make sense to make `BaseEntity` and even `BaseDAO` abstract, but I left that out for brevity. – Thomas Jan 24 '12 at 13:24
  • can we discuss about this with more details? for via mail or via skype? It is will be hard for you? – user471011 Jan 24 '12 at 15:25
  • @user471011 Unfortunately I don't have that much time right now, since I'm at work. – Thomas Jan 24 '12 at 15:42
  • @user471011 if you have more questions you might ask them here. Others could help or might find the information useful as well. – Thomas Jan 24 '12 at 15:47
  • I created new question here: http://stackoverflow.com/questions/8990750/correct-design-for-entity-classes-need-recommendations If you have free time, please, gime me answer. – user471011 Jan 24 '12 at 16:55
1

If you want to use generics you should define Dao as following:

public interface Dao<T extends Persistent> {
    .....................
    void save(T persistent);
    ...................
}

Now when you extend it you will have to create save that accepts Book only:

public class Book extends Dao<Book> {
    .....................
    void save(Book persistent);
    ...................
}

The benefit here is that you cannot pass Author to BookDao. This will not pass compilation.

BTW if you are using Hibernate, JPA or other ORM solution you do not really have to create DAO per entity. One generic dao can solve all your needs.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • 1
    Actually `void save(Book persistent);` wouldn't even be necessary if the implementation doesn't differ from the base one. – Thomas Jan 24 '12 at 09:29
  • 1
    @Thomas, I 100% agree with you. I even wrote that he does not need DAO per entity at all. One generic implementation is good enough. – AlexR Jan 24 '12 at 09:38
0

There is no reason here. If it's unique, it's not generic, by definition ! List getAll() will do the Job.

The ArrayList is Generic because it will sometimes return Persistent, sometime President.

Nicolas Zozol
  • 6,910
  • 3
  • 50
  • 74