I have a very interesting problem: I'm using a hibernate session factory with a RoutingDataSource (for 2 data sources). I'm using 2 facades in my service layer which also defines my transactions boundaries. I'm combining the service layer and data access layer into one layer. Each facade interacts with a different data source. I thought this would be a perfect application using an Aspect - intercept the calls to the service layer to determine which data source to use for the hibernate session. Below are the relevant classes:
And here is my intercepting class:Code:public interface HibernateDao { public <T> T get(Long id, Class<T> clazz); public <T> List<T> find(Class<T> clazz, int start, int limit); ... } @Repository public abstract class AbstractHibernateDaoImpl extends HibernateDaoSupport implements HibernateDao { @SuppressWarnings("unchecked") @Transactional public <T> T get(Long id, Class<T> clazz) { return (T)getHibernateTemplate().load(clazz, id); } @SuppressWarnings("unchecked") @Transactional public <T> List<T> find(Class<T> clazz, int start, int limit) { Criteria criteria = getSession().createCriteria(clazz); .. return criteria.list(); } } public interface FooFacade extends HibernateDao { public List<Product> findProductsByTitle(String title); } public class FooFacadeImpl extends AbstractHibernateDaoImpl implements FooFacade { @SuppressWarnings("unchecked") @Transactional public List<Product> findProductsByTitle(String title) { ... return some list; } } public interface BarFacade extends HibernateDao { public List<Bar> findBarByTitle(String title); } public class BarFacadeImpl extends AbstractHibernateDaoImpl implements BarFacade { @SuppressWarnings("unchecked") @Transactional public List<Bar> findBarByTitle(String title) { ... return some list; } }
When I call a method from a controller to one of the business facades (i.e.,FooFacade or BarFacade) the call is only being intercepted by my DataSourceInterceptor if the method is defined on the Facade interface( findProductsByTitle() ). In other words, if the method is implemented by AbstractHibernateDaoImpl it will NOT be intercepted. Code example:Code:@Aspect @Order(100) public class DataSourceInterceptor { @Before("execution(* com.abc..FooFacade.*(..))") public void setFooDataSource() { log.info("...method intercepted, setting datasource to foo......"); StoreContextHolder.setStore(Store.FOO); } @Before("execution(* com.abc..BarFacade.*(..))") public void setBarDataSource() { log.info("...method intercepted, setting datasource to bar......"); StoreContextHolder.setStore(Store.BAR); } }
How do I intercept the methods implemented by AbstractHibernateDaoImpl?Code:@Controller @RequestMapping("/somurl") public class SomeController { @Autowired private FooFacade fooFacade; @Autowired private BarFacade barFacade; @RequstMapping public String handleRequest(String title) { // this method will get intercepted, method is implemented by // fooFacadeImpl fooFacade.findProductsByTitle(title); // this method will NOT be intercepted, method is implemented by // AbstractHibernateDaoImpl. An exception will occur indicating the table or // view cannot be found barFacade.get(new Long(10), Bar.class); // this method will be intercepted, method is implemented by facade barFacade.findBarByTitle(title); } }


Reply With Quote
