Spring 3.0 added a lot of features to be java 5 compatible. Many methods are parametrized now.
For example HibernateTemplate.executeXXX()
, HibernateTemplate.getXXX()
, HibernateTemplate.mergeXXX()
return T,
HibernateTemplate.loadAll()
returns List<T>
.
But findXXX()
methods return plain List
, so I have to cast it to something like List<MyEntity>
.
Does somebody know what is the reason? Why find methods are not param开发者_JAVA技巧etrized? Or probably there is other, parametrized API?
here is what I am doing.
This is the relevant part of spring.xml:
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor" autowire="byName" /><!--sessionFactory will get autowired-->
<bean id="deviceDaoTarget" class="com.nso.solution.dao.DeviceDAOHibernateImpl" autowire="byName" /><!--sessionFactory will get autowired-->
<bean id="discoveryDAO" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.nso.solution.dao.DeviceDAO</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
<value>deviceDaoTarget</value>
</list>
</property>
</bean>
DeviceDAO is an interface that contain several methods that allow to retrieve, save and delete the objects. DeviceDAOHibernateImpl implements this interface, e.g.
public List<Device> getAllDevices() {
return getHibernateTemplate().loadAll(Device.class);
}
I had to mark this method with @SuppressWarnings("unchecked") annotation.
Spring didn't update HibernateTemplate because it is deprecated in Spring 3. (See Classic Spring Usage: Hibernate)
Spring suggests a simpler usage of Hibernate, that doesn't tie application code to the Spring Framework.
Basically: inject a SessionFactory
, use @Transactional
and do plain hibernate coding while Spring automatically creates and commits transactions:
@Transactional
public class ProductDaoImpl implements ProductDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@SuppressWarnings("unchecked")
public Collection<Product> loadProductsByCategory(String category) {
return this.sessionFactory.getCurrentSession()
.createQuery(
"from test.Product product where product.category=?")
.setParameter(0, category)
.list();
}
}
Update: this is Spring's sample code, not mine, but I changed it to return a generic collection. No casting required. (But you have to enforce type safety yourself, the compiler can't help you)
i would go with the sessionfactory example above und extend it to
public List<T> findByCriteria(Class<T> persistentClass, Criterion... criterion) {
Criteria crit = getSessionFactory().getCurrentSession().createCriteria(persistentClass);
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
}
just use it without Criterions if you want all rows
The thing is that Hibernate guys don't want to use generics in Hibernate API. As far as I know their argument is that they don't want force Java 1.4 people to switch to 1.5. HibernateTemplate
doesn't convert search results to the parametrized type in order to stay consistent with the original (non-generic) Hibernate API.
精彩评论