Re-establishing a db connection after a network failure - Hibernate - java

Hello everyone,
I am using hibernate ORM and oracle database. My cfg file has following properties:
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:#url</property>
<property name="connection.username">username</property>
<property name="connection.password">pasword</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">3</property>
Everything works fine, but when I run the application and if I unplug network cable and plug it agian my db queries fail. It gives me the error
java.sql.SQLException: Io exception: Connection reset by peer: socket write error
Is there any way to re establish the connection?

You need to configure your database connection pool - not hibernate.Try setting idleConnectionTestPeriod and an appropriate preferredTestQuery, e.g., select 1 from dual.
See How To Configure The C3P0 ConnectionPool for more information. You'll get the most control if you create a c3p0.properties file in WEB-INF/classes but you need to make sure not to override those properties in your hibernate.cfg.xml.
Well I had written c3p0-config.xml like
<c3p0-config>
<default-config>
<!-- Configuring Connection Testing -->
<!-- property name="automaticTestTable">TEST_EMS_HIBERNATE_CONN</property -->
<property name="checkoutTimeout">0</property>
<property name="testConnectionOnCheckout">true</property>
<property name="testConnectionOnCheckin">false</property>
<property name="preferredTestQuery">SELECT 1 from dual</property>
<!-- Configuring Recovery From Database Outages -->
<property name="acquireRetryAttempts">0</property>
<property name="acquireRetryDelay">1000</property>
<property name="breakAfterAcquireFailure">false</property>
<!-- Configuring to Debug and Workaround Broken Client Apps -->
<property name="unreturnedConnectionTimeout">1800</property>
<property name="debugUnreturnedConnectionStackTraces">true</property>
</default-config>
and the system properties like:
C3P0_SYS_PROPS="-Dcom.mchange.v2.c3p0.cfg.xml=<FILE-PATH>/c3p0-config.xml -Dcom.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog -Dcom.mchange.v2.log.FallbackMLog.DE
FAULT_CUTOFF_LEVEL=WARNING"

As I see, you have specified when test connection, but have not specified how to test them. Read it http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing . I guess you should just add preferredTestQuery, usually it's something like SELECT 1 FROM DUAL.
Also read here Something wrong with Hibernate DB connection pooler c3p0

Related

Hibernate 5.2 encrypt configuration properties

In my application build on Hibernate 5.2.11 there are many hibernate configuration file with username, password and connection url.
I would like to encrypt that data.
My configuration file is like this:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:localhos</property>
<property name="connection.username">username</property>
<property name="connection.password">passowrd123</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
</session-factory>
</hibernate-configuration>
Any suggestion?
Use a property placeholder then add your database config to a properties file on the server:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:${configDir}/database.properties</value>
</property>
</bean>
Then
<property name="connection.url">${url}</property>
<property name="connection.username">${username}</property>
<property name="connection.password">${passowrd}</property>
Then your database.properties which is securely on the server will be
url=jdbc:oracle:localhost
usuername=username
password=passowrd123
Then when you start your java app add a system parameter to define the configDir location, for example:
.... -DconfigDir=/opt/config
See examples here
Generally - encrypting/hiding anything what resides on the client's side (workstation/mobile/..) you can consider more like obfuscation or encoding.
In theory - you may set the Hibernate properties programatically (see Setting properties programmatically in Hibernate) reading your data from an encrypted file.
The problem is - where do you put your encryption keys? The keys has to be available to the application anyway somewhere.

Existing code throws this error [Hibernate + c3p0 + Oracle11g]: a resourcepool could not acquire a resource from its primary factory or source

when i am trying to connect to a test db which settings as per shown, i am faced all the errors as per mentioned.
most of the config is taken from working production environment but i am not able to connect to my test db.
i have tried various methods and it just fails to run properly.
Im able to connect test db via other methods such as PLSQL developer or SQLPLUS.
The errors i am getting in a bunch are :
org.hibernate.exception.GenericJDBCException: Cannot open connection
....
....
....
Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
....
....
....
Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.j‌​ava:1422)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResour‌​cePool.java:606)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool‌​.java:526)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse‌​(C3P0PooledConnectionPool.java:756) at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0P‌​ooledConnectionPool.java:683)
this is my config file for hibernate :
<session-factory>
<property name="hibernate.connection.url">jdbc:oracle:thin:#ipaddress:1521:dbname</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="connection.autoReconnect">true</property>
<property name="connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">1</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.timeout">50000</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.validate">false</property>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<mapping resource etc>
</session-factory>
Can anyone help me on this issue?
It happen for many reason like
The database configuration details you have entered are incorrect or have changed, e.g. the database name or database username/password for your Confluence database.
1)The URL for the database is incorrect.
2)The database server is not running. If your database server is down, restart it and check the logs to see why it had failed or stopped.
3)The network is down (or there is a firewall in between confluence and the database server which is interfering) and the connection to the database cannot be established.
4)Your database password has expired.
5)Check your driver,if its present or not in your class-path.

how to check that I am using c3p0 in hibernate?

I am change my hibernate.cfg.xml added new options:
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="show_sql">true</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/pirates</property>
<property name="connection.username">postgres</property>
<property name="connection.password">mmm888</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">200</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.generate_statistics">true</property>
and added hibernate-c3p0-4.1.4.Final.yar in my project, but I'm not sure that I'm using c3p0. I can set hibernate.c3p0.max_size = 2 but Hibernate continues to create 400 ( 400 -for example) threads - if it needs to.
how to check that I am using c3p0 in hibernate ?
You are missing this line:
<property name="connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider"/>
This tells Hibernate to use the C3P0 connection pool.
Not sure the above answer is necessary, according to C3P0ConnectionProvider document:
https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/connection/C3P0ConnectionProvider.html
It says:
"A connection provider that uses a C3P0 connection pool. Hibernate will use this by default if the hibernate.c3p0.* properties are set."
Check here.
Generally speaking, applications should not have to configure a
ConnectionProvider explicitly if using one of the Hibernate-provided
implementations. Hibernate will internally determine which
ConnectionProvider to use based on the following algorithm:
If hibernate.connection.provider_class is set, it takes precedence
else if hibernate.connection.datasource is set → Using DataSources
else if any setting prefixed by hibernate.c3p0. is set → Using c3p0
else if any setting prefixed by hibernate.proxool. is set → Using
Proxool
else if any setting prefixed by hibernate.hikari. is set → Using
Hikari
else if hibernate.connection.url is set → Using Hibernate’s built-in
(and unsupported) pooling
else → User-provided Connections
Other than this, the fastest way to check is to go in database server and see whether the idle connection have been created or not.

Hibernate and mysql timeout issue

I have been having trouble with Hibernate and Mysql timeout error.I am also using properties of c3p0(connection provider). After my Hibernate/MySQL have been running after 8 hours(which is default timeout value in Mysql), I have the exception. But it doesn't help.
property for auto reconnect also not working.
Here is my Hibernate Configuration:
<property name="connection_provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
**<property name="connection.autoReconnect"> true</property>
<property name="connection.autoReconnectForPools">true</property>**
<property name="connection.is-connection-validation-required">true</property>
<property name="c3p0.validate">true</property>
<property name="current_session_context_class">thread</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_second_level_cache">false</property>
<property name="c3p0.idle_test_period">20</property>
<property name="c3p0.timeout">40</property>
<property name="c3p0.max_size">100</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.acquireRetryAttempts">10</property>
<property name="c3p0.maxPoolSize">100</property>
<property name="c3p0.maxIdleTime">300</property>
<property name="c3p0.maxStatements">50</property>
<property name="c3p0.minPoolSize">10</property>
<property name="c3p0.preferredTestQuery">select 1;</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/doqeap</property>
<property name="connection.user">root</property>
<property name="connection.password">*******</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.jdbc.batch_size">0</property>
<mapping></mapping>
please help me to sort out this problem.
Thanks
If the Connection timeout is the issue, then Connection testing should eliminate, wither via tests on checkout (reliable but imposes a client visible performance cost) or tests on checking + idle tests.
Looking at you config params, it looks like you mean to set tests on checkouts and idle tests. I'd expect that c3p0 would eliminate timed out Exceptions before your app saw them. If that hasn't happened, it'd be interesting to see two things: 1) c3p0's config, which gets logged at INFO when the pool is initialized -- is c3p0, through the hibernate layer, seeing the configuration you intend? 2) the Exception that your app receives when it encounters the stale Connections.
Good luck!

How can I configure Hibernate to use SSL to talk to the DB server?

I have an existing java webapp that uses Hibernate for it's persistence. I've been told that I have to have to talk to the DB encrypted - so my first thought is to set it up to do the communication via SSL - and went through figured out how to set up Oracle to listen for JDBC over SSL -
http://www.oracle.com/technology/tech/java/sqlj_jdbc/pdf/wp-oracle-jdbc_thin_ssl_2007.pdf
And wrote a quick test class to verify that it was setup and working (connecting via standard JDBC). That left me with the issue of configuring Hibernate - unfortunately I don't see how hibernate supports it?
Hibernate works with standard JDBC data sources, so there is no need for Hibernate-specific configuration.
Here's an quick example that should work when configuring Hibernate with Spring:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL"><value><!-- JDBC URL that specifies SSL connection --></value></property>
<!-- other relevant properties, like user and password -->
<property name="connectionProperties>
<value>
oracle.net.ssl_cipher_suites: (ssl_rsa_export_with_rc4_40_md5, ssl_rsa_export_with_des40_cbc_sha)
oracle.net.ssl_client_authentication: false
oracle.net.ssl_version: 3.0
oracle.net.encryption_client: REJECTED
oracle.net.crypto_checksum_client: REJECTED
</value>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- classes etc -->
</bean>
Try this:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://blablaba:8443/dbname?useSSL=true</property>
<property name="hibernate.connection.verifyServerCertificate">false</property>
<property name="hibernate.connection.requireSSL">true</property>
<property name="hibernate.connection.autoReconnect">true</property>
<property name="hibernate.connection.username">bablablab</property>
<property name="hibernate.connection.password">clclclclc</property>
related links
http://www.razorsql.com/articles/mysql_ssl_jdbc.html
http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-using-ssl.html
http://www.javabeat.net/qna/164-hibernate-jdbc-and-connection-properties/
Please add following property in Hibernate configuration file to enable SSL :
<property name="hibernate.connection.verifyServerCertificate">false</property>
<property name="hibernate.connection.useSSL">true</property>
Should be handled by the driver but you may have to do some configuration. Oracle Docs
I had the jdbcURL
jdbc:postgresql://jdbcurl?sslmode=require&sslrootcert=location_to_cert1&sslcert=location_to_cert2&sslkey=location_to_cert3.
All I had to do was to replace all the & with &.
My new jdbcURL looks like
jdbc:postgresql://jdbcurl?sslmode=require&sslrootcert=location_to_cert1&sslcert=location_to_cert2&sslkey=location_to_cert3

Categories