patternjavaMinor
Correct DAO implementation?
Viewed 0 times
daoimplementationcorrect
Problem
This is my first go at implementing the DAO pattern - let alone implementing it for MongoDB with Morphia - I was hoping someone could point out smells and answer questions from my below implementation.
My implementation of
All of my DTO's are coded against interfaces - this is so that I can use things like Morphia's annotations in my DTO's without coupling that specific DTO to any implementation technology.
```
public interface EntryDTO extends GenericDTO
{
}
@Entity
public class EntryDTOMongoImpl implements EntryDTO
{
@Id
private ObjectId id;
private String name;
private int age;
private ArrayList pets;
public EntryDTOMongoImpl()
{
this.name = "Colin";
this.age = 40;
this.pets = new ArrayList();
pets.add("dog");
pets.add("cat");
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public ObjectId getId()
{
return id;
}
public void setId(ObjectId id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public ArrayList getPets()
public interface GenericDAO
{
public void insert(T entity);
public T queryByKey(Class typeClass, K id);
}My implementation of
GenericDAO for MongoDB extends Morphia's BasicDAO - does this seem like the correct placement for this extension? The super I'm leveraging is performing the connection for me, if I was to drop Morphia and use something else, I would have to change the constructors for each of my DAO implementations, and achieve connection in a different way - is this a common kind of change people make to their DAO definition?public class GenericDAOMongoImpl extends BasicDAO
{
public GenericDAOMongoImpl(Class entityClass) throws UnknownHostException
{
super(entityClass, ConnectionManager.getDataStore());
}
}All of my DTO's are coded against interfaces - this is so that I can use things like Morphia's annotations in my DTO's without coupling that specific DTO to any implementation technology.
```
public interface EntryDTO extends GenericDTO
{
}
@Entity
public class EntryDTOMongoImpl implements EntryDTO
{
@Id
private ObjectId id;
private String name;
private int age;
private ArrayList pets;
public EntryDTOMongoImpl()
{
this.name = "Colin";
this.age = 40;
this.pets = new ArrayList();
pets.add("dog");
pets.add("cat");
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public ObjectId getId()
{
return id;
}
public void setId(ObjectId id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public ArrayList getPets()
Solution
I disagree with
You design generic dao with to generic type
-
What happen with this design if in a part of application we have an entity with two key as
-
What happen with this design if we want more operation in data layer such as
I suggest following design:
I show your application by my suggest design:
first I define a entity for sample it's
Next define an interface as
In next step, we define implementation for
Now, we designed dao layer for
In next step we define an implementation for above factory, in this case we want define
saw we define a spring implementation of dao factory with context files path. We in next step show a sample of spring context:
and in last we define a
and use
With this define we separating
Generic DAO design, reason of it is : You design generic dao with to generic type
T, K, T for entity type and K for entity id. Now I say: -
What happen with this design if in a part of application we have an entity with two key as
primary key (We have this allow in ORM)-
What happen with this design if we want more operation in data layer such as
search or batch insert operations.I suggest following design:
- Have for any entity a interface with itself operation.
- Have for any entity a or more implementation of above interface
- Have an interface as
DAOFactory
- Have a or more implementation of
DAOFactory(such asSpringimplementation orGuiceor manually or etc)
I show your application by my suggest design:
first I define a entity for sample it's
Person:public class Person
{
private long id;
private String name;
private int age;
/*
* define accessible methods
*/
}Next define an interface as
DAO for above entity:public interface PersonDAO
{
public void insert(Person entity);
public Person queryByKey(long id);
public void remove(long id);
public List searchByCriteria(/*custom criteria*/);
}In next step, we define implementation for
PersonDAO interface by MongoDB:public class MongoDBPersonDAO implements PersonDAO
{
public void insert(Person entity)
{
/*
* MongoDB api for insert an entity
*/
}
public Person queryByKey(long id)
{
/*
* MongoDB api for find an entity by its id
*/
}
public void remove(long id)
{
/*
* MongoDB api for remove an entity by its id
*/
}
public List searchByCriteria(/*custom search criteria*/)
{
/*
* MongoDB api for find set of entity by set of search criteria
*/
}
}Now, we designed dao layer for
Person entity. In next step we have to define a Factory API: public DAOFactory
{
public PersonDAO getPersonDAO();
/*
* define other abstract methods for other DAOs
*/
}In next step we define an implementation for above factory, in this case we want define
Spring implementation:public SpringDAOFactory implements DAOFactory
{
private ApplicationContext dao_ctx;
/*
* define constructor that spring context files parameter
*/
public SpringDAOFactory(String...contexts)
{
this.dao_ctx = new ClassPathXmlApplicationContext(contexts);
}
public PersonDAO getPersonDAO()
{
return dao_ctx.getBean(PersonDAO.class);
}
}saw we define a spring implementation of dao factory with context files path. We in next step show a sample of spring context:
and in last we define a
singleton dao factory by spring implementation as following:DAOFactory dao_factory = new SpringDAOFactory(); // this instance have to singletonand use
dao_factory where need to it.With this define we separating
DAO APIs from its implementation and PersonDao from its implementations also. With this design any entity has itself dao and its operations.Code Snippets
public class Person
{
private long id;
private String name;
private int age;
/*
* define accessible methods
*/
}public interface PersonDAO
{
public void insert(Person entity);
public Person queryByKey(long id);
public void remove(long id);
public List<Person> searchByCriteria(/*custom criteria*/);
}public class MongoDBPersonDAO implements PersonDAO
{
public void insert(Person entity)
{
/*
* MongoDB api for insert an entity
*/
}
public Person queryByKey(long id)
{
/*
* MongoDB api for find an entity by its id
*/
}
public void remove(long id)
{
/*
* MongoDB api for remove an entity by its id
*/
}
public List<Person> searchByCriteria(/*custom search criteria*/)
{
/*
* MongoDB api for find set of entity by set of search criteria
*/
}
}public DAOFactory
{
public PersonDAO getPersonDAO();
/*
* define other abstract methods for other DAOs
*/
}public SpringDAOFactory implements DAOFactory
{
private ApplicationContext dao_ctx;
/*
* define constructor that spring context files parameter
*/
public SpringDAOFactory(String...contexts)
{
this.dao_ctx = new ClassPathXmlApplicationContext(contexts);
}
public PersonDAO getPersonDAO()
{
return dao_ctx.getBean(PersonDAO.class);
}
}Context
StackExchange Code Review Q#8769, answer score: 4
Revisions (0)
No revisions yet.