I wonder if it would be possible to have a single method in the DAOFactory classes that takes as a parameter something indicating the DAO you want and returns an instance of that DAO.
The reason I ask is that I was using some of the code from the CE application and I saw the comment in the class javadocs for the class DAOFactory
Quote:
* Implementation: If you write a new DAO, this class has to know about it.
* If you add a new persistence mechanism, add an additional concrete factory
* for it to the enumeration of factories.
I kind of took this as a challenge because I work with a model that has a couple of hundred entities and I don't fancy having to do this manually so I thought I'd try something and lo! The following fell onto my screen.
Code:
/**
* @param Class The class for which you want a DAO instance.
* @return GenericDAO An instance of GenericDAO matching the persistentClass.
* @author Vaughn Butt
*/
@Override
public GenericDAO getDAO(Class persistentClass) {
String persistedClassCanonicalName = persistentClass.getCanonicalName();
String className = persistedClassCanonicalName
.substring(persistedClassCanonicalName.lastIndexOf('.') + 1);
String daoPackageName = this.getClass().getPackage().getName();
String daoClassCanonicalName = daoPackageName + "." + className + "DAO"+"Hibernate";
try {
Class daoClass = Class.forName(daoClassCanonicalName);
Class[] parameterTypes = new Class[]{Session.class};
Constructor constructor = daoClass.getConstructor(parameterTypes);
GenericDAO dao = (GenericDAO) constructor.newInstance(new Object[]{getCurrentSession()});
return dao;
}
catch (ClassNotFoundException e) {
throw new DAOException(e);
} catch (SecurityException e) {
throw new DAOException(e);
} catch (NoSuchMethodException e) {
throw new DAOException(e);
} catch (IllegalArgumentException e) {
throw new DAOException(e);
} catch (InstantiationException e) {
throw new DAOException(e);
} catch (IllegalAccessException e) {
throw new DAOException(e);
} catch (InvocationTargetException e) {
throw new DAOException(e);
}
}
Where DAOException is a RuntimeException.
You need to cast the returned value like so:
Code:
HibernateDAOFactory factory = new HibernateDAOFactory();
ItemDAO dao = (ItemDAO) factory.getDAO(Item.class);
This code assumes a few things:
If the entity is called Foo then the DAO is called FooDAOHibernate.
The DAO is in the same package as the HibernateDAOFactory class.
Probably something I haven't realised.
I think it might be possible to have this method in the abstract DAOFactory class if you use declare the method
Code:
protected abstract String getPersistenceType();
,implement it in each concrete DAOFactory subclass and replace the String "Hibernate" with the method invocation.
So...
Is it a good idea?
Is it worth it?
Will it even work?
Is it a crap implementation?
Feedback appreciated - even "It's a crap idea because...".
VB