Hi all,
First of all, thank you for your replies, very much appreciated. A newbie in Spring here as well and I may get some terms wrong (if must, please correct me)
As for the question I'm about to ask, is there a possible way for me to create dynamic loading of beans without defining them in applicationContext.xml.
My situation is that, my application will interact with multiple databases. One of the database connection (in this case, HSQLDB) will be set in the applicationContext.xml where else the others will be defined in the HSQLDB database table DYNAMIC_DATABASE_CONNECTION. The code snippets below was a success somehow, I was able to initialize multiple database connection using a HibernateConnectionsContext class. The problem here is that, upon shutting down the application server (in this case I am using Tomcat), it failed to shutdown. Tomcat just halts with the exception thrown
Code:
INFO: Stopping Coyote HTTP/1.1 on http-8080
Exception in thread "HSQLDB Timer @bf5555" java.lang.NullPointerException
at org.hsqldb.lib.HsqlTimer.nextTask(Unknown Source)
at org.hsqldb.lib.HsqlTimer$TaskRunner.run(Unknown Source)
at java.lang.Thread.run(Thread.java:619)
WEB-INF/applicationContext.xml
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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
<bean id="dataSource1" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource">
<bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager"><ref local="jotm"/></property>
<property name="driverName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:C:/dev/apache-tomcat-6.0.10/data/localDB</value>
</property>
</bean>
</property>
<property name="user">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource1"/>
</property>
<property name="mappingResources">
<list>
<value>conf/hbm/DynamicDatabaseConnection.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager1" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<ref local="jotm"/>
</property>
</bean>
<bean id="dynamicDBConnections" class="com.custom.HibernateConnectionsContext">
</bean>
</beans>
com.custom.HibernateConnectionsContext
Code:
public class HibernateConnectionsContext
implements BeanFactoryPostProcessor, ApplicationContextAware
{
public void postProcessBeanFactory(final ConfigurableListableBeanFactory context)
throws BeansException
{
xaDatasource = new org.enhydra.jdbc.standard.StandardXADataSource();
Object jotmFactoryBeanObj = mainContext.getBean("jotm");
xaDatasource.setTransactionManager((TransactionManager)jotmFactoryBeanObj);
xaDatasource.setDriverName("org.gjt.mm.mysql.Driver");
xaDatasource.setUrl("jdbc:mysql://localhost:3306/mydatabase");
poolDataSourceBeanName = "dataSource2";
poolDatasource = new RootBeanDefinition(org.enhydra.jdbc.pool.StandardXAPoolDataSource.class);
poolDatasource.getPropertyValues().addPropertyValue("dataSource", xaDatasource);
poolDatasource.getPropertyValues().addPropertyValue("user", "myuser");
poolDatasource.getPropertyValues().addPropertyValue("password", "mypassword");
registry.registerBeanDefinition(poolDataSourceBeanName, poolDatasource);
sessionFactoryBeanName = "sessionFactory2";
sessionfactory = new RootBeanDefinition(LocalSessionFactoryBean.class);
Object poolDataSourceObj = mainContext.getBean(poolDataSourceBeanName);
sessionfactory.getPropertyValues().addPropertyValue("dataSource", poolDataSourceObj);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQLMyISAMDialect");
hibernateProperties.put("hibernate.hbm2ddl.auto", "update");
sessionfactory.getPropertyValues().addPropertyValue("hibernateProperties", hibernateProperties);
registry.registerBeanDefinition(sessionFactoryBeanName, sessionfactory);
}
}
Here are my references to design what I need:
- Multiple database connection
- Dynamic bean loading
All i need is the ability to somehow create those database connections (SPRING+HIBERNATE) dynamically without going through the applicationContext.xml
Any help or comments are greatly appreaciated. Thank you once again.
Extra note:
If i define my connections in applicationContext.xml, it all works and no errors are thrown and able to shutdown Tomcat properly. By somehow, had i coded something wrong which made the bean initialization failed thus causing the application server (Tomcat) failed to shutdown?