I have a wicket page , which contains two Spring-managed beans , one is DAO , another is Service Object :
public class MergeAccountsPage extends WebPage
{
@SpringBean
private MergeEmailDao mergeEmailDao;
@SpringBean
private MergingService mergingService;
}
The MergingService
's implementation's methods are mostly annotated with @Transactional
, so every action involving MergingService works fine.
But the problem comes here :
Link<Void> link = new Link<Void>("cancelLink") {
@Override
public void onClick() {
ma.setNewEmail(null);
ma.setNewEmailClicked(null);
ma.setNewEmailSentTime(null);
mergeAccoungDao.update(ma); //not written to DB
setResponsePage(...);
}
};
The link will call mergeAccoungDao.update(ma)
to update a row in DB.
But the data is not updated to DB , I think it is because the DAO is not wrapped in @Transaction nor tx:advice
and aop
tags.
I wonder is there a way to programmatically get the transaction manager , and manually open/close the transaction ?
Note: I can solve the problem by adding this code in spring's XML :
<tx:advice id="txAdviceApp" transaction-manager="transactionManagerApp">
<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"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="methods" expression="execution(* destiny.utils.AbstractDao+.*(..))"/>
<aop:advisor advice-ref="txAdviceApp" pointcut-ref="methods"/>
</aop:config>
So that the DAO's save/update/delete will work like a charm.
But I'd not like to add this config . Because in fact , the DAO extends an AbstractDao , and there are other DB/DAOs extend this AbstractDao :
public interface AbstractDao<T> {
public T get(Serializable id);
public T save(T t);
public T update(T t);
public void delete(T t);
}
public abstract class AbstractDaoJpaImpl<T> implements AbstractDao<T>
public interface MergeAccountDao extends AbstractDao<MergeAccount>
@Repository
public class MergeAccountDaoImpl extends AbstractDaoJpaImpl<MergeAccount> implements MergeAccountDao
Therefore , if this AbstractDAO's CRUD is "adviced" by this transactionManagerApp , other DAOs may have problem , because other DAOs may depend on txManagerForum , txManagerBank , txManagerUser ...etc.
Back to the problem , is there a way to programmatically get txManager ? Such as :
TransactionManager txManager = TxManagerThreadLocal.get();
txManager.begin();
ma.setNewEmailSentTime(null);
mergeAccoungDao.update(ma);
txManager.commit();
Or is there any better way to wrap a transaction to the DAO ?
Thanks a lot.