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.
public interface GenericDAO<T, K extends Serializable>
{
public void insert(T entity);
public T queryByKey(Class<T> 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<T, K extends Serializable> extends BasicDAO<T, K>
{
public GenericDAOMongoImpl(Class<T> 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<String> pets;
public EntryDTOMongoImpl()
{
this.name = "Colin";
this.age = 40;
this.pets = new ArrayList<String>();
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<String> getPets()
{
return pets;
}
public void setPets(ArrayList<String> pets)
{
this.pets = pets;
}
}
Then my DAO implementation for EntryDTO
reads below. Does it make sense that the EntryDAO
interface is parameterized such that it accepts a generic variable that extends EntryDTO
? I was hoping I could simply parameterize it with EntryDTO
as the generic type, but this causes issues in the below Runner
class when I pass the concrete Class
EntryDTOMongoImpl.class
to the queryByKey
method?
public interface EntryDAO<T extends EntryDTO> extends GenericDAO<T, Serializable>
{
}
public class EntryDAOMongoImpl extends GenericDAOMongoImpl<EntryDTOMongoImpl, ObjectId> implements EntryDAO
{
private static final Logger logger = Logger.getLogger(EntryDAOMongoImpl.class);
public EntryDAOMongoImpl(Class<EntryDTOMongoImpl> entityClass) throws UnknownHostException
{
super(entityClass);
}
public void insert(Object entity)
s
save((EntryDTOMongoImpl) entity);
}
public Object queryByKey(Class typeClass, Serializable id)
{
EntryDTOMongoImpl dto = null;
try
{
dto = (EntryDTOMongoImpl) ConnectionManager.getDataStore().get(typeClass, id);
}
catch(UnknownHostException ex)
{
logger.error(ex);
}
return dto;
}
}
I'm then creating instances of my DAO's simply like below. This would ideally be done with some DI library.
public class Runner
{
private static final Logger logger = Logger.getLogger(Runner.class);
private EntryDAO entryDAO;
public Runner() throws UnknownHostException
{
this.entryDAO = new EntryDAOMongoImpl(EntryDTOMongoImpl.class);
}
public static void main(String[] args) throws UnknownHostException
{
Runner runner = new Runner();
EntryDTOMongoImpl dtoA = new EntryDTOMongoImpl();
runner.entryDAO.insert(dtoA);
EntryDTOMongoImpl foundA = (EntryDTOMongoImpl) runner.entryDAO.queryByKey(EntryDTOMongoImpl.class, dtoA.getId());
logger.debug(dtoA.getId() + ", " + dtoA.getName());
logger.debug(foundA.getId() + ", " + foundA.getName());
}
}