I have a web application that currently uses c3p0 and Hibernate to connect to a Firebird 1.5 database.
I am facing a problem from time to time where the database just stops responding, even trying to manually restart the service doesn't have any effect, and it doesn't generate any logs, so I have to manually reboot the machine to get it working again.
I think that maybe Firebird hangs when the pool tries to acquire a specific number of connections or something like that. So, I need to test my app without connection pooling, to check if this is or is not the problem.
I can't simply remove c3p0 configs from persistence because this way Hibernate would use its own integrated connection pool. So how to do it?
The most flexible solution is to use an explicit DataSource, instead of configuring the connection pooling through Hibernate. One option to configure a non-pooling DataSource is by using DriverManagerDataSource:
#Override
protected Properties getProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
//log settings
properties.put("hibernate.hbm2ddl.auto", "update");
//data source settings
properties.put("hibernate.connection.datasource", newDataSource());
return properties;
}
protected ProxyDataSource newDataSource() {
DriverManagerDataSource actualDataSource = new DriverManagerDataSource();
actualDataSource.setUrl("jdbc:hsqldb:mem:test");
actualDataSource.setUsername("sa");
actualDataSource.setPassword("");
ProxyDataSource proxyDataSource = new ProxyDataSource();
proxyDataSource.setDataSource(actualDataSource);
proxyDataSource.setListener(new SLF4JQueryLoggingListener());
return proxyDataSource;
}
This way you can choose a pooling or a non-pooling DataSource.
To get a better understanding of you connection pooling resources usage, you can configure FlexyPool to collect metrics for:
concurrent connections
concurrent connection requests
data source connection acquiring time
connection lease time
maximum pool size
total connection acquiring time
overflow pool size
retries attempts
I found documentation for hibernate 3.3 and 4.3 that says:
Just replace the hibernate.connection.pool_size property with
connection pool specific settings. This will turn off Hibernate's
internal pool.
Hibernate will use its org.hibernate.connection.C3P0ConnectionProvider
for connection pooling if you set hibernate.c3p0.* properties
So remove hibernate.connection.pool_size and any hibernate.c3p0... properties from configuration, than connection pooling is disabled.
Adding to Vlad's answer:
If somebody still faces this:
Be sure to remove "hibernate-c3p0" from your classpath, if exists, since this will automatically enable MChange c3p0 connection pool.
Another option that, you can close the connection manually when closing the entity manager:
....
SessionImpl ses = (SessionImpl) session;
close(ses.connection());
try {
session.close();
} catch (Exception e) {
logger.error(e);
}
........
Note: the above manual closing will work with the default pool of hibernate, not hibernate default one.
Good Luck
Related
I'm trying to understand when exactly a database connection is aquired in an application that uses hibernate as an ORM & Spring for transaction management.
In this article, it says:
If the transaction manager decides to create a new transaction, then it will:
create a new entity manager
bind the entity manager to the current thread
grab a connection from the DB connection pool
bind the connection to the current thread
However here it says :
Hibernate defers the database connection acquisition until the current transaction has to execute its first SQL statement (either triggered by a read or a write operation). This optimization allows Hibernate to reduce the physical transaction interval, therefore increasing the chance of getting a connection from the pool.
I can't understand how can Hibernate delay the connection aquisition if Spring decides to aquire it before.
I can't understand how can Hibernate delay the connection aquisition
if Spring decides to aquire it before.
The decision is taken by the transaction manager and so potentially by the JpaTransactionManager/HibernateTransactionManager
Hibernate 5.2.0 introduces new property hibernate.connection.provider_disables_autocommit
With this Hibernate can delay the database connection acquisition until there is a JDBC Statement to execute. otherwise the database connection is acquired when entering the #Transactional service method.
So to allow Spring wires this property into the JPATransactionManager during the setup of spring context you have to set this property in your application.properties/yaml -->
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
Last thing required to do this --> setAutoCommit to false on the connection pool provider (by default HikariCP since Spring boot 2)
spring.datasource.hikari.auto-commit=false
I used to have a tomcat connection pool configuration restricting the initial pool size: spring.datasource.tomcat.initial-size=2
Now switching to hikaricp: what is the equivalent to restrict the initially started connections?
Sidenote: spring.datasource.hikari.minimumIdle does not prevent initializing 10 connections at startup.
You can use these properties provided in spring boot:
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=8
and then:
spring.datasource.hikari.idleTimeout=120000
to limit the life of idle connections, but hikari doesn't give you such property for initial number of connections.
With spring boot, set these properties in your application.properties.
spring.jpa.hibernate.hikari.minimumIdle=5
spring.datasource.hikari.maximum-pool-size=10
I just found out it had to do with my configuration of multiple datasources.
In general, the property spring.datasource.hikari.minimum-idle=2 automatically restricts the startup pool size correctly!
But if having multiple data sources, there was a configuration property missing, as follows:
#Bean
#ConfigurationProperties("spring.datasource.secondary.hikari")
public DataSource secondatyDataSource() {
return ...
}
Before I just had "spring.datasource.secondary", and there by my property "spring.datasource.secondary.hikari.*" was not taken into account.
This is probably wrong documented in
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html
If I load a City object from DB using Hibernate session, and then using the same session which has not been used for an hour, if I do a city.getCountry() which should lazy load the Country object, I get an Exception (Connection marked as broken because of SQLSTATE(08003)). I got two general questions:
Is lazy loading just another new JDBC connection and totally
independent connection under the hood?
What kind of parameters in hibernate connection pool configuration I
need to tune to increase the timeout for these kind of situations?
I'm not using transactions.
I'm using HikariCP and my DB is Postgrsql.
I'm using a Connection via severals pools :
DataSource ds = initialContext.lookup("poolname1");
Connection cn = ds.getConnection();
submethod1(cn);
submethod2(cn);
void submethod1(Connection cn)
{
// using connection
// ..
}
My question is: how to log "poolname" in submethods ? or similar informations about DataSource.
Perhaps this will help
getClientInfo()
or
getMetaData()
as mentionned in the Official Java Doc
The poolname in your example is actually a JNDI Name. This is generally a configuration which is configured in resource definition (e.q under in tomcat config).
For your problem as #sourlcheck mentioned, its not possible as connection are not aware of their datasource.
Once way to solve your problem is to give label to the datasource. Most of the Pooled datasource implementations (e.q. C3P0) offer a setter for setting up a name to the datasource. In C3P0 the datasournce class is ComboPooledDataSource and the method is getDataSourceName(). Once you get this name, it remains the same throughout its life cycle. But off course you need to introduce third party library
You can't log "poolname" in methods that receive Connection. Connections don't know if they are pooled or served directly from non-pooling DataSource.
Also you can create and access your pool in many different ways, not all of them guaranteeing existence of "poolname".
I'm just starting to learn Jboss AP6 and I have a few questions:
I created Local Tx Datasource (MySql Database)and can access it in my code using JNDI.
Now I would like to create kind of Transaction Management resource inside of my Jboss AP.
1) Is there any JTA feature built in Jboss AP6?
2) Can I apply it to my local DataSource which I created?
3) Can you please point me to any documentation which explains how to configure it and use it in my code, ot is there any article which coversthese topics in depth?
I googled it for some period of time, but haven't found any useful documentation. I don't want to use Spring/Hibernate out of the box solution just Mysql and plain JTA.
JBoss AP6 support JTA 1.1
Yes you can
If you declareLocalTxDatasource, this is mean, than whenever you get
connection from this datasource this connection will participate in "current" transaction.
If you want to manupulate transaction yourself, without EJB for example, you must enject TransactionManager from JNDI.
Example
TransactionManager tm = (TransactionManager)context.lookup("java:/TransactionManager");
tm.begin();
try{
DataSource ds = context.lookup("java:/testDS");
connection = ds.getConnection()
//do useful work
connection.close();
tm.commit();
}catch(Exception e){
tm.rollback()
}