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>
Related
I am miagrating my database from MySql to H2 and I keep getting the error message
org.h2.jdbc.JdbcSQLException: Table "DEVICE" not found
Everything was mapped correctly and worked with MySql. I only changed the context.xml file to work with H2 and added a dependency for H2 in the Pom.xml file.
context.xml file:
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/dataStore2"/>
<property name="username" value="" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
The Device class:
package com.entities;
#Entity
#Table(name="DEVICE")
public class Device {
...
}
You're missing
<prop key="hibernate.hbm2ddl.auto">create</prop>
in
<property name="hibernateProperties">
to force Hibernate to create schema based on entity classes if it is missing. You also need to change dialect from MySQL to H2:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.entities" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
Reference: Hibernate, Chapter 3. Configuration, Table 3.7. Miscellaneous Properties
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)
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?