Results 1 to 4 of 4

Thread: Inject Datasource to JPA Persistence DAO Layer Programmatically

  1. #1

    Default 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="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
          xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                                              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                                              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
          <bean id="transactionManager"
                class="org.springframework.transaction.jta.JtaTransactionManager">
                <property name="transactionManagerName" value="${transaction.jndi}" />
                <property name="userTransactionName" value="UserTransaction" />
          </bean>
    
          <!--
                Creates a EntityManagerFactory for use with the Hibernate JPA provider
          -->
          <bean id="entityManagerFactory"
                class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                <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>
                </property>
          </bean>
     
          <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
                <property name="jndiName" value="${database.jndi}" />
          </bean>
    
          <bean id="genericDAO" class="com.sample.dao.GenericDAOImpl">  
                <property name="entityManagerFactory" ref="entityManagerFactory"/>  
          </bean>
    
          <tx:annotation-driven proxy-target-class="true"
                transaction-manager="transactionManager" />
    </beans>

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    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.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Smile

    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.

    Code:
    @Component
    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);
    			jndiObjectFactoryBean.afterPropertiesSet();
    			
    			HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    			hibernateJpaVendorAdapter.setDatabasePlatform("com.hibernate.dialect.Oracle9iDialect");
    			hibernateJpaVendorAdapter.setShowSql(true);
    			hibernateJpaVendorAdapter.setGenerateDdl(false);
    			
    			LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
    			entityManagerFactory.setDataSource((DataSource) jndiObjectFactoryBean.getObject());
    			entityManagerFactory.setPersistenceUnitName("Sample");
    			entityManagerFactory.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
    			entityManagerFactory.setJpaVendorAdapter(hibernateJpaVendorAdapter);
    			entityManagerFactory.afterPropertiesSet();
    			
    			((GenericDAOImpl)genericDAO).setEntityManagerFactory(entityManagerFactory.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. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    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.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •