Hi!
My first message in this community
I'm having issues when configuring Spring + Hibernate.
I have an interface HibernateDao<T> :
Then, the concrete DAO classes implements that interface and the @Transactional annotations in the methods.Code:public interface HibernateDao<T> extends Dao<T> { public void setSessionFactory(SessionFactory sessionFactory); public List<T> getAll(); public T get(Integer id); public T insert(T add); public T update(T update); public void delete(Integer id); public Integer getCount(); public T getNext(Integer previousId); public List<T> getRange(Integer startRow, Integer endRow, Ordenacion[] sortBy, Map<String, Object> filterCriteria); }
Here is my configuration XML:Code:public class ActividadDAOHibernate implements HibernateDao<Actividad> { private SessionFactory sessionFactory; @Override public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @SuppressWarnings("unchecked") @Override @Transactional(readOnly=true) public List<Actividad> getAll() { return (List<Actividad>) sessionFactory.getCurrentSession() .createCriteria(Actividad.class).list(); } @Override @Transactional(readOnly=true) public Actividad get(Integer id) { return (Actividad) sessionFactory.getCurrentSession().get( Actividad.class, id); } @Override @Transactional public Actividad insert(Actividad add) { Integer id = (Integer) sessionFactory.getCurrentSession().save(add); add.setId(id); return add; } //... }
Finally I have this this test:Code:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <context:property-placeholder location="classpath:env.properties" /> <!--========== TransactionManager ========== --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- ========= Para usar @Transactional =========== --> <tx:annotation-driven transaction-manager="txManager" /> <!--========== /TransactionManager ========== --> <!--========== Hibernate SessionFactory ========== --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><!-- <property name="dataSource"> <ref bean="dataSource" /> </property> --> <property name="hibernateProperties"> <props> <prop key="hibernate.connection.driver_class">${hibernate.connection.driver_class}</prop> <prop key="hibernate.connection.password">${hibernate.connection.password}</prop> <prop key="hibernate.connection.url">${hibernate.connection.url}</prop> <prop key="hibernate.connection.username">${hibernate.connection.username}</prop> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="current_session_context_class">${hibernate.current_session_context_class}</prop> </props> </property> <property name="annotatedClasses"> <list> <value>es.aevum.gwt.aevumerp.shared.domain.Actividad</value> </list> </property> </bean> <bean id="actividadDao" class="es.aevum.gwt.aevumerp.server.persistence.dao.hibernate.ActividadDAOHibernate"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </beans>
Code:public class ActividadDAOHibernateTest { private static ApplicationContext ctx; private static ActividadDAOHibernate dao; @BeforeClass public static void setUpBeforeClass() throws Exception { ctx = new ClassPathXmlApplicationContext("beans.xml"); Object o = ctx.getBean("actividadDao"); dao = (ActividadDAOHibernate) o; } @Test public void testGetAll() { List<Actividad> list = dao.getAll(); assertNotNull(list); assertEquals("Se espera una lista con dos elementos", 2, list.size()); } @Test public void testGet() { Actividad act = dao.get(1); assertNotNull(act); assertEquals("Se espera que el id sea 1", new Integer(1), act.getId()); assertEquals("Se espera que el código sea 1", new Integer(1), act.getCodigo()); assertEquals("Se espera que el nombre sea act1", "act1", act.getNombre()); }
When I execute the test I get this exception in the @BeforeClass method:
Well, I know that if I configure the annotation-driven this way:Code:java.lang.ClassCastException: $Proxy12 cannot be cast to es.aevum.gwt.aevumerp.server.persistence.dao.hibernate.ActividadDAOHibernate at es.aevum.gwt.aevumerp.server.persistence.dao.hibernate.ActividadDAOHibernateTest.setUpBeforeClass(ActividadDAOHibernateTest.java:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
then the problem is solved.Code:<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
The problem is that without the proxy-target-class="true" I only get the exception IF THE HibernateDao<T> INTERFACE HAVE THE GENERIC TYPE (T).
If my DAO doesn't implement any interface or if the interface doesn't have the generic type (i.e. HibernateDao) I don't get the Exception without proxy-target-class="true".
So, IMHO is probably an issue in the ProxyFactory (¿?) when the Proxied class implements an interface with a Generic Type (:S)
In addition I would like to implement the @Transactional annotation in the HibernateDao<T> interface, which is not possible with proxy-target-class="true"
What can I do??
Thank you!
- Luis



Reply With Quote
