Announcement Announcement Module
No announcement yet.
Inject Datasource to JPA Persistence DAO Layer Programmatically Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inject Datasource to JPA Persistence DAO Layer Programmatically

    I am using a DAO class that extends JpaDaoSupport. The datasource from JNDI tree is injected to ContainerEntityManagerFactoryBean and this is in turn injected to DAO class. I will get to know the JNDI name of the data source only at runtime. Is there any approach/suggestions to handle this scenario and still utilize all the dependency injections and spring based-transactions.

    In this scenario, the DAO layer beans will be prototype and all the logic in the same except that i should be able to select the JNDI programmatically at run time. Any suggestions / approach is appreciated.

    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns=""
          xmlns:xsi="" xmlns:p=""
          xmlns:context="" xmlns:tx=""
          <bean id="transactionManager"
                <property name="transactionManagerName" value="${transaction.jndi}" />
                <property name="userTransactionName" value="UserTransaction" />
                Creates a EntityManagerFactory for use with the Hibernate JPA provider
          <bean id="entityManagerFactory"
                <property name="dataSource" ref="dataSource" />
                <property name="persistenceUnitName" value="${persistentUnitName}" />
                <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
                <property name="jpaVendorAdapter">
                      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                            <property name="databasePlatform" value="${hibernate.dialect}" />
                            <property name="showSql" value="true" />
                            <property name="generateDdl" value="false" />
          <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
                <property name="jndiName" value="${database.jndi}" />
          <bean id="genericDAO" class="com.sample.dao.GenericDAOImpl">  
                <property name="entityManagerFactory" ref="entityManagerFactory"/>  
          <tx:annotation-driven proxy-target-class="true"
                transaction-manager="transactionManager" />

  • #2
    Use the search as that question has been answered a couple of times. In short you could use a AbstractDynamicRoutingDataSource (if you know all datasources up-front) or you could use something like this which is a more flexible than the ADRDS.


    • #3
      Thanks Marten for your reply. In our case, the data sources are not known up-front. The JNDI of the various data sources are configured in the database and can be changed if required. Currently we have written a look-up kind of class to create that dao class with the data sources injected manually.

      Below is the code snippet.

      public class GenericDAOLookup {
      	private Map<String, GenericDAO> genericDAOMap = new HashMap<String, GenericDAO>();
      	public GenericDAO lookupGenericDAO(String jndi) throws NamingException {
      		GenericDAO genericDAO;
      		if(genericDAOMap.containsKey(jndi)) {
      			genericDAO = genericDAOMap.get(jndi);
      		} else {
      			genericDAO = new GenericDAOImpl();
      			JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
      			jndiObjectFactoryBean.setJndiName("java:" + jndi);
      			HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
      			LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
      			entityManagerFactory.setDataSource((DataSource) jndiObjectFactoryBean.getObject());
      			genericDAOMap.put(jndi, genericDAO);
      		return genericDAO;
      I am unable to understand the second approach using ContextSwappableTargetSource. Will surely try it out and let you know.


      • #4
        We basically used that approach to be able to deploy new customers without restarting the server. We had a naming convention and we simply put the static files for the web somewhere and created a new datasource in jndi and that was all that was needed to deploy a new customer. The code is on github here, I recently updated it for spring 3.

        The beauty of this solution is you don't need multiple dao's, entitymanagers etc.