Environment : spring-framework-2.5.6.SEC01 , hibernate-distribution-3.3.2.GA , hibernate-entitymanager-3.4.0.GA
I am trying to use <tx:advice> and <aop: pointcut> to declare my transaction in my spring xml file , the config is as following :
In my DaoMiningJpaImpl , it is very simple :Code:<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="methods" expression="execution(* destiny.data.mining.DaoMining.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="methods"/> </aop:config> <tx:annotation-driven transaction-manager="transactionManager"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="daoMining" class="destiny.data.mining.DaoMiningJpaImpl"/>
It works very well ... Untill.... I want to implement an "Abstract Dao Pattern" :Code:public class DaoMiningJpaImpl implements DaoMining { @PersistenceContext(unitName="mining") private EntityManager em; @Override public Person get(Serializable id){ return em.find(Person.class, id); } @Override public Person save(Person p){ return em.merge(p); } @Override public Person update(Person p) { return em.merge(p); } @Override public void delete(Person p) { em.remove(em.merge(p)); } }
First , I created an AbstractDao :
Then I created an AbstractDaoJpaImpl that implements AbstractDao :Code:public interface AbstractDao<T> { public T get(Serializable id); public T save(T t); public T update(T t); public void delete(T t); }
Then I created DaoMiningImpl that extends AbstractDaoJpaImpl :Code:public abstract class AbstractDaoJpaImpl<T> implements AbstractDao<T> , Serializable { private EntityManager em; private Class<T> clazz; public AbstractDaoJpaImpl(EntityManager em , Class<T> clazz) { this.em = em; this.clazz = clazz; } @Override public T get(Serializable id) { return em.find(clazz, id); } @Override public T save(T t) { //em.getTransaction().begin(); em.persist(t); //em.getTransaction().commit(); return t; } @Override public T update(T t) { return em.merge(t); } @Override public void delete(T t) { em.remove(em.merge(t)); } }
Then I change my xml file to :Code:public class DaoMiningImpl extends AbstractDaoJpaImpl<Person> implements DaoMining { public DaoMiningImpl(EntityManagerFactory emf) { super(emf.createEntityManager(), Person.class); } }
But now , the transaction fails , all save/update/delete actions are not written to DB.Code:<aop:config> <aop:pointcut id="methods" expression="execution(* destiny.utils.AbstractDao.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="methods"/> </aop:config> <tx:annotation-driven transaction-manager="transactionManager"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="daoMining" class="destiny.data.mining.DaoMiningImpl"> <constructor-arg ref="entityManagerFactory"/> </bean>
It seems <tx:advice> and <aop: pointcut> cannot declare transactions into this Abstract Dao Pattern ...
I tried to add @Transactional to DaoMiningImpl and AbstractDaoJpaImpl , but both not working.
The only way to make it working is adding em.getTransaction().begin() and em.getTransaction().commit() to AbstractDaoJpaImpl :
But that's not what I want . I want a declarative transactionCode:@Override public T save(T t) { em.getTransaction().begin(); em.persist(t); em.getTransaction().commit(); return t; }
Could anybody tell me how to solve it ? thanks !


Reply With Quote