I want to define a routingdatasource for two different databases: mysql and oracle
I've defined the following config.xml
<bean id="dataSourceTarget" class="com.test.common.RoutingDataSource">
<property name="targetDataSources">
<map key-type="com.test.common.DataSourceType">
<entry key="MY_SQL" value-ref="mySqlDataSource"/>
<entry key="ORACLE" value-ref="oracleDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="mySqlDataSource"/>
</bean>
<bean id="mySqlDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver.classname}" />
<property name="jdbcUrl" value="${mysql.url}" />
<property name="user" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</bean>
<bean id="oracleDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="${oracle.url}" />
<property name="user" value="${oracle.user}" />
<property name="password" value="${oracle.passw}" />
</bean>
and now I can define session factory and transaction manager
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
</props>
</property>
</bean>
But this is doesn't work. I'm getting the
Caused by: java.lang.UnsupportedOperationException: The user must supply a JDBC connection
And in addition I must define the dialect for session.
But how can I define it depending on the datasourse it is working on?
Related
I have a Java Batch Program which is triggered from a BPEL process used for inserting set of Record into DB.
Size of record might vary but at an average around 20,000 to 40,000.
My custom java batch picks up the data from an excel uploaded from a third party app into server location.
For performing the DML operation I have gone with Hibernate/Spring JDBC framework.
Refer to my spring configuration file as below::
<context:component-scan base-package="mybasepackage" />
<bean id="myProps"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:myDB.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${DB_DRIVER}" />
<property name="url" value="${DB_URL}" />
<property name="username" value="${DB_USER}" />
<property name="password" value="${DB_PASSWORD}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="mypackage" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">10</prop>
<prop key="hibernate.c3p0.max_size">7000</prop>
</props>
</property>
</bean>
<bean id="myBatchDao"
class="mypackage.MyBatchDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="myBatchService"
class="mypackage.MyBatchServiceImpl">
<property name="myBatchDao" ref="myBatchDao" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
I am already using c3p0 for ConnectionPooling and also visited the following links:
link1
link2
But still I am getting following exception::
<org.hibernate.engine.jdbc.spi.SqlExceptionHelper> <BEA-000000> <IO Error: Got minus one from a read call, connect lapse 6370 ms., Authentication lapse 0 ms.>
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction;nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:564)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
I'm working with Hibernate. How can I configure my applicationContext.xml to have an H2 in-memory databaseorg.hibernate.dialect.H2Dialect dont work
Spring configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost/~/test" />
<property name="username" value="sa" />
<property name="password " value="" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
You are not connecting to an in-memory database. Your JDBC URL is for network connection to localhost:
jdbc:h2:tcp://localhost/~/test
To use the in-memory H2 the URL must look like this, containing mem:
jdbc:h2:mem:testdb
In the manual, see the section on In-Memory Database
Use embedded db datasource (with dbcp connection pool) instead of drivermanager datasource.
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:db/sql/create-db.sql" />
<jdbc:script location="classpath:db/sql/insert-data.sql" />
</jdbc:embedded-database>
<bean id="dbcpDataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:hsqldb:mem:dataSource" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dbcpDataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
I remix Spring Data and Hibernate in my Application to access MS-SQL Data.
In My All Service class,I set #Transactional(readOnly=true) in front of the class name.Recently,I observe some DB Table Locks occurrence.
Otherwise,I set#Transactional(readOnly=true,isolation = Isolation.READ_UNCOMMITTED) to avoid DB Table lock,but it throws
org.springframework.transaction.InvalidIsolationLevelException: Standard JPA does not support custom isolation levels - use a special JpaDialect for your JPA implementation.
How can I modify the XML to use isolation = Isolation.READ_UNCOMMITTED for dirty read?
<!-- JPA Configurations -->
<!-- <jee:jndi-lookup id="myContactDataSource" jndi-name="jdbc/GNWEB" lookup-on-startup="false"
proxy-interface="javax.sql.DataSource"/> -->
<!-- use annotation in Service: #Transactional -->
<bean id="transactionManager2" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<qualifier value="transactionManager2"/>
</bean>
<bean id="oracleConnection" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/OracleDB</value>
</property>
</bean>
<bean id="oracleTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="oracleConnection" />
<qualifier value="oracleConnectionTransactionManager"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="mssqlDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="url">
<value>${connection.url}</value>
</property>
<property name="username">
<value>${connection.username}</value>
</property>
<property name="password">
<value>${connection.1qaz#WSX}</value>
</property>
</bean>
<bean id="auditInterceptor" class="com.bot.gnweb.unit.AuditIntercepter"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy">
<property name="dataSource" ref="mssqlDataSource" />
<property name="entityInterceptor" ref="auditInterceptor"/>
<property name="packagesToScan">
<value>com.bot.gnweb.model</value>
</property>
<property name="mappingResources">
<list>
<value>gnwebSql.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.dialect">com.bot.gnweb.model.MssqlCustomDialect</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="auditInterceptor">
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
<property name="persistenceUnitName" value="gnWebPU" />
<property name="dataSource" ref="mssqlDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
</bean>
<!-- Spring Data -->
<jpa:repositories base-package="com.bot.gnweb.repository"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager" />
<bean id="auditorBean" class="com.bot.gnweb.model.AuditingAware" />
<jpa:auditing auditor-aware-ref="auditorBean" />
I'm new in spring and trying to switch between 2 different DBs. I've made these changes in spring configuration xml file:
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:config/db-config.properties" />
</bean>
<!-- MS Sql DB -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<!-- end -->
<!-- MySql DB -->
<bean id="dataSourceMySql"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver1}" />
<property name="url" value="${db.url1}" />
<property name="username" value="${db.username1}" />
<property name="password" value="${db.password1}" />
</bean>
<!-- end -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.epam.model" />
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto"></prop>
<prop key="hibernate.dialect"> org.hibernate.dialect.SQLServerDialect</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="entityManagerFactoryMySql"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.epam.model" />
<property name="dataSource" ref="dataSourceMySql" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto"></prop>
<prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManagerMySql" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryMySql" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:annotation-driven transaction-manager="transactionManagerMySql" />
<jpa:repositories base-package="com.epam.repository" />
</beans>
what I need to add in repository or service to specify which db I want to work.
You can load the second data source using #Resource annotation
Thanks for responce. I'm just added 2nd db specific key/values in properties file and depending on the db type, just uncommented appropriate ones.
I have multiple data sources and the dynamic session mapping used to work fine when I used "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" Now I have upgraded my application to hibernate 4 and started using "org.springframework.orm.hibernate4.LocalSessionFactoryBean". For some reason hibernate is not able to map the tables from my second data source.
Here are my configs.
<bean id="DataSource1" class="org.apache.commons.dbcp.BasicDataSource"
autowire="byName" destroy-method="close">
<property name="driverClassName" value="$api{d1.jdbc.driver}" />
<property name="url" value="$api{d1.jdbc.url}" />
<property name="username" value="$api{d1.jdbc.username}" />
<property name="password" value="$api{d1.jdbc.password}" />
<property name="maxActive" value="$api{dbcp.maxActive}" />
<property name="maxWait" value="$api{dbcp.maxWait}" />
<property name="minIdle" value="$api{dbcp.minIdle}" />
<property name="maxIdle" value="$api{dbcp.maxIdle}" />
<property name="validationQuery" value="$api{dbcp.validationQuery}" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="d1SessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
autowire="byName">
<property name="dataSource" ref="DataSource1" />
<property name="annotatedClasses">
<list>
<value>com.class1</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
</props>
</property>
</bean>
<bean id="d1Dao" class="com.DaoImpl"
autowire="byName">
<property name="sessionFactory" ref="d1SessionFactory"></property>
</bean>
And the second session definition is
<bean id="DataSource2" class="org.apache.commons.dbcp.BasicDataSource"
autowire="byName" destroy-method="close">
<property name="driverClassName" value="$api{d1.jdbc.driver}" />
<property name="url" value="$api{d1.jdbc.url}" />
<property name="username" value="$api{d2.jdbc.username}" />
<property name="password" value="$api{d2.jdbc.password}" />
<property name="maxActive" value="$api{dbcp.maxActive}" />
<property name="maxWait" value="$api{dbcp.maxWait}" />
<property name="minIdle" value="$api{dbcp.minIdle}" />
<property name="maxIdle" value="$api{dbcp.maxIdle}" />
<property name="validationQuery" value="$api{dbcp.validationQuery}" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="d2SessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
autowire="byName">
<property name="dataSource" ref="DataSource2" />
<property name="annotatedClasses">
<list>
<value>com.class2</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
<prop key="hibernate.transaction.auto_close_session">true</prop>
</props>
</property>
</bean>
<bean id="d2Dao" class="com.DaoImpl"
autowire="byName">
<property name="sessionFactory" ref="d2SessionFactory"></property>
</bean>
At run time when I do
Session session = this.sessionFactory.openSession() ;
The session always corresponds to d1SessionFactory even when dao is d2Dao.
Not sure what am I doing wrong here.
The same config worked fine when I was using "AnnotationSessionFactoryBean"
Help is appreciated.
The error I get is as follows
org.hibernate.hql.internal.ast.QuerySyntaxException: Class2 is not mapped [FROM Class2 WHERE user_id = :value0 AND active = :value1] at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180) at
org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110) at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:93) at
org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:326) at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3252) at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3141) at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:694) at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:550) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:287) at
org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:235) at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:248) at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183) at
org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) at
org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:101) at
org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:80) at
org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:119) at
org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:215) at
org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:193) at
org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1649)