How can I connect to more than one mysql database dynamically using Hibernate?
I believe in Spring you can have multiple SessionFactories each using a separate DataSource. You could pass the specific SessionFactory to the appropriate DAO.
If you use hibernate with out spring you can have multiple hibernate properties xml for each database. In those xml files you can specify the database host,username,password ,database name and other connection properties. You can create multiple session Factories using xml files and use the correct session factory in DAO classes.
Create a Class which contains HibernateProperties and SessionFactory entities.
Something like:
public class HibernateSessionFactory {
private static final long serialVersionUID = 1L;
private static Log log = LogFactory.getLog(HibernateSessionFactory.class);
private Resource[] mappingLocations;
private Properties hibernateProperties;
private SessionFactory factory;
It'll be nice if you could later use Spring and inject this class with the database connection details, and later assign this HibernateSessionFactory to the related DAO classes.
I did it before, more or less it looks like this:
<bean id="mapHibernateFactory"
class="com.geofencing.dao.hibernate.HibernateSessionFactory"
init-method="init" destroy-method="dispose" scope="singleton">
<property name="mappingResources">
<list>
..... your hibernate mapping files .....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">false</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.connection.isolation">4</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.connection.url">${jdbc.url}</prop>
<prop key="hibernate.connection.username">${jdbc.username}</prop>
<prop key="hibernate.connection.password">${jdbc.password}</prop>
<prop key="hibernate.connection.driver_class">${jdbc.driverClassName}</prop>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">WEB-INF/ehcache.xml</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
<prop key="hibernate.connection.zeroDateTimeBehavior">convertToNull</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="hibernate.connection.autoReconnectForPools">true</prop>
</props>
</property>
</bean>
Not sure how to do it with annotation though.
Related
I have following bean:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql">
<value>${hibernate.show_sql}</value>
</property>
<property name="generateDdl">
<value>${generateDdl}</value>
</property>
<property name="databasePlatform">
<value>${databasePlatform}</value>
</property>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop>
<prop key="hibernate.archive.autodetection">${hibernate.archive.autodetection}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.comment_sql">${hibernate.comment_sql}</prop>
<!-- optimization settings -->
<prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<!-- c3p0 connection pool settings -->
<prop key="hibernate.c3p0.acquire_increment">${hibernate.c3p0.acquire_increment}</prop>
<prop key="hibernate.c3p0.idle_test_period">${hibernate.c3p0.idle_test_period}</prop>
<prop key="hibernate.c3p0.timeout">${hibernate.c3p0.timeout}</prop>
<prop key="hibernate.c3p0.maxIdleTime">${hibernate.c3p0.maxIdleTime}</prop>
<prop key="hibernate.c3p0.min_size">${hibernate.c3p0.min_size}</prop>
<prop key="hibernate.c3p0.max_size">${hibernate.c3p0.max_size}</prop>
<prop key="hibernate.c3p0.max_statements">${hibernate.c3p0.max_statements}</prop>
<prop key="hibernate.c3p0.min_pool_size">${hibernate.c3p0.min_pool_size}</prop>
<prop key="hibernate.c3p0.max_pool_size">${hibernate.c3p0.max_pool_size}</prop>
<prop key="hibernate.c3p0.preferredTestQuery">${hibernate.c3p0.preferredTestQuery}</prop>
<prop key="hibernate.c3p0.idleConnectionTestPeriod">${hibernate.c3p0.idleConnectionTestPeriod}</prop>
<prop key="hibernate.c3p0.autocommit">${hibernate.c3p0.autocommit}</prop>
<!-- second level cache settings -->
<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
<prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
</props>
</property>
</bean>
Can anyone explain to me whats the difference between hibernate.connection.autocommit and hibernate.c3p0.autocommit? Also there are another equal properties . Whats the difference? Also what happens if they are different which one will prevail?
According to the c3p0 documentation :
autoCommitOnClose Must be set in c3p0.properties, C3P0 default: false
The JDBC spec is unfortunately silent on what should happen to unresolved, pending transactions on Connection close. C3P0's default policy is to rollback any uncommitted, pending work. (I think this is absolutely, undeniably the right policy, but there is no consensus among JDBC driver vendors.) Setting autoCommitOnClose to true causes uncommitted pending work to be committed, rather than rolled back on Connection close.
As hibernate.c3o0.autocommit drives this settings, we can say that the difference is that hibernate.connection.autocommit is just like wrapping every query with begin transaction; and then commit.
Both are not recommended.
I have a problem with c3p0. Last time I configured c3p0 as dataSource in application because Quartz Scheduler opened new connection for every check, now is ok but from this time application doesnt respond after about 30mins, sometimes more. There is no logs in catalina or application logs file. Other applications work normally on the same server. On this application I got 404. I returned to default Spring data source and removed configuration and everything works.
What can cause the problem ?
Tomcat 8.0.21
c3p0.version 0.9.5.1
Hibernate version 4.3.1.Final
Configuration
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driver}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<property name="hibernateProperties">
<props>
<!-- HIBERNATE CONFIGURATION -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> -->
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<!-- HIBERNATE SEARCH CONFIGURATION -->
<prop key="hibernate.search.default.directory_provider">filesystem</prop>
<prop key="hibernate.search.default.indexBase">${hibernate.search.local}</prop>
<!-- CONNECTIONS POOLING CONFIGURATION -->
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.idle_test_period">1</prop>
<prop key="hibernate.c3p0.max_size">60</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.min_size">30</prop>
<prop key="hibernate.c3p0.timeout">0</prop>
</props>
</property>
</bean>
Update with new settings:
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.idle_test_period">1000</prop>
<prop key="hibernate.c3p0.max_size">60</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.min_size">20</prop>
<prop key="hibernate.c3p0.timeout">100</prop>
Still same, one user, 1h:40min
I want to do: #Autowire Session session. For hibernate 3, the process is described here. it uses ...hibernate3.SessionFactoryUtils.getSession. but in spring 3.2 there is no such method in ...hibernate4.SessionFactoryUtils
Great changes have taken place in Spring3.x, a few days ago I met the same problem, Through the offical document we know that Spring won't provide HibernateTemplate and HibernateDaoSupport any longer, we are advised to use Hibernate pure API, and about your confusion here is my solution:
first, define a sessionFactory bean in applicationContext.xml,
<!-- sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.bbs.*.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${hibernate.dialect}
</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost/bbs</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.username">root</prop>
<prop key="hibernate.connection.password">123456</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
and then, in your DAO
#Autowired
#Qualifier("sessionFactory")
private SessionFactory sessionFactory;
public Session getSession() {
return sessionFactory.getCurrentSession();
}
in this way you'll get the hibernate session, then do what you want, just enjoy it:)
While using spring + hibenate alongwith Websphere server I am getting this exeption
org.hibernate.TransactionException: Could not register synchronization
Hibernate properties in spring config file is
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.datasource">jdbc/jndiName</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.connection.aggressive_release">false</prop>
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.connection.pool_size">5</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
</props>
WebSphere itself handles all pooling and cache level for its Data sources. All JDBC related configurations can be performed through WebSphere administrative console. So writing
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.connection.datasource">jdbc/jndiName</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
</props>
is sufficient in Spring.
I found some threads saying this was doable, but did not find specific instructions or config information.
I want to do this from Beanstalk as well: the app should get deployed to beanstalk with a config that points hibernate to the elasticache instance(s).
Yes, we were able to configure hibernate with 2nd level cache.. Not with beanstalk though.. This code should help you with it.
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
<!-- prop key="hibernate.hbm2ddl.auto" >update</prop -->
<prop key="hibernate.jdbc.batch_size">100</prop>
<prop key="hibernate.cache.provider_class">com.googlecode.hibernate.memcached.MemcachedCacheProvider
</prop>
<!-- Cache disabled -->
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.memcached.servers"><elasticachehostname>:11211</prop>
<prop key="hibernate.memcached.cacheTimeSeconds">300</prop>
<prop key="hibernate.memcached.connectionFactory">DefaultConnectionFactory</prop>
<prop key="hibernate.memcached.clearSupported">false</prop>
</props>
You would need the hibernate memcached jar as well