View Full Version : Converting to Generics
steinard
04-03-2007, 12:39 PM
I've just refactored my DAOs to use the generic version of HibernateTemplate. And thus I've also run into the problem of generic type specification. In several places the actual type and return type cannot be specified at compile time. Thus I have to use reflection to resolve the type and then specify the resolved type at runtime or introduce a big design change to the framework (which I would rather not).
So, for example this statement must be rewritten:
User user = HibernateTemplate.Execute(new HibernateDelegate<User>(delegate(ISession session)
{
ICriteria criteria = session.CreateCriteria(entityType);
criteria.Add(Expression.Like("UserName", userName));
HibernateTemplate.PrepareCriteria(criteria);
return (User) criteria.UniqueResult();
}));
My current problem is how to create at runtime through reflection an instance of the HibernateDelegate<T> to be of the resolved type and then inject the actual method body/delegate on the instance??
Thanks,
Steinar.
boriska
04-03-2007, 02:33 PM
Hello,
one or two weeks ago I played with a generic aproach.
Based on the info founded at http://www-128.ibm.com/developerworks/java/library/j-genericdao.html
I implemented a test object.
The config section for it was :
<object name="StatusDAO" type="DataAccessLayer.Spring.DAO.Hibernate.GenericDAO<Do mainModel.Domain.Status, long>, DataAccessLayer">
<property name="HibernateTemplate" ref="HibernateTemplate" />
</object>
Doing so I read 4.2.4. Object creation of generic types in chaper 4 of the ref doc.
I don't know if you have already looked into it.
May be you can find there some information.
Regards,
boris
steinard
04-03-2007, 02:50 PM
Hi!
Yes, it's smart not to repeat the DAO, but sometimes you would like a subclass where you can create your very efficient HQL or criterias as winding through loops isn't nearly as efficient. Another approach would be to have one dao and pass the dao the criterias, but I would like to have all the hql or criterias defined in one logical place.
Anyway, even writing one generic statement becomes quite hard when you do not have the types needed at codetime, for instance; You have the type IUser, but you have no clue about which classes implements this interface and will be used. Then you call your service, saying that you would retrieve a user of type IUser with username "Blush". The service might resolve the type (based on DI) and replace it with the actual type, then you must use reflection to create the criteria as you cannot place <User> in the brackets. So, writing the same thing for collections is even worse...
For instance, this works for the LoadAll method on HibernateTemplate:
Type[] arg = new Type[] { entityType };
MethodInfo mi = HibernateTemplate.GetType().GetMethod("LoadAll").MakeGenericMethod(arg);
return (IList)mi.Invoke(HibernateTemplate, new object[] { });
Another modification of this one works for the Load method, but the Execute method is more difficult because I need a way to define the HibernateDelegate first. Basically, this boils down to reflection exercises, or I must refactor a whole lot of code and let other layers see the actual implementations....
Thanks,
Steinar.
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.