My application has long running transactions and hence I tried the option session.close() at the end of every method to ensure that the connection objects are not held indefinitely for long time.
When session.close() option is used, I could see that the Hibernate's session object and the corresponding Connection object obtained from session.connection() are destroyed properly. But the issue is with the connection pool. The connection obtained by the session is not released back to the connection pool even after closing the session. Other requests are found waiting for connection from the pool.
I am using JTA transaction in my application. In hibernate.cfg.xml, I have set connection.release_mode to auto (default) and connection.autocommit to true.
Has anyone faced this issue? Please let me know what am I missing here.
Follow-up: This is my hibernate configuration file details:
<property name="connection.datasource">MXoraDS</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.release_mode">after_statement</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.JTASessionContext</property>
<property name="transaction.auto_close_session">true</property>
<property name="max_fetch_depth">2</property>
We use JSF and EJB 2.1 at the application layer connecting to Oracle DB. The after_statement doesn't seem to release the connection to the pool. Please let me know if u need any more details.
I am using JTA transaction in my application. In hibernate.cfg.xml, I have set connection.release_mode to auto (default) and connection.autocommit to true.
Could you try to define the hibernate.connection.release_mode property to after_statement explicitly? I know this is supposed to be the default but, depending on your context (could you be using Spring?), auto might not behave as expected (see here and here).
For reference, here is what the Table 3.4. Hibernate JDBC and Connection Properties writes about the property hibernate.connection.release_mode:
Specifies when Hibernate should
release JDBC connections. By default,
a JDBC connection is held until the
session is explicitly closed or
disconnected. For an application
server JTA datasource, use
after_statement to aggressively
release connections after every JDBC
call. For a non-JTA connection, it
often makes sense to release the
connection at the end of each
transaction, by using
after_transaction. auto will
choose after_statement for the JTA
and CMT transaction strategies and
after_transaction for the JDBC
transaction strategy.
e.g. auto (default) | on_close | after_transaction |
after_statement
This setting only affects Sessions
returned from
SessionFactory.openSession. For
Sessions obtained through
SessionFactory.getCurrentSession, the
CurrentSessionContext implementation
configured for use controls the
connection release mode for those
Sessions. See Section 2.5,
“Contextual sessions”
If it doesn't help, please add more details about your environment and configuration (Spring?), how you get the session, etc.
if you are using the JDBCTransactionManager, the connection will be returned to the connectionpool when the transactions ends.
Related
I am trying to use EclipseLink JPA for a sample java application. I am trying to configure the connection pool related settings in the persistence.xml, but I could not find any suitable property for specifying the minimum Idle connections to be maintained in the connection pool. I was not able to find any details around this property or idle connection time out property in the Eclipselink documentation, here. Can someone please point me to the documentation links that I am looking for?
We're facing huge versions upgrade of the codebase, in that codebase we're using hibernate and jdbi to connect to a postgres 12 db.
JDBI version is not changed in this upgrade, Hibernate version was 5.1.5.Final and has been updated to 5.3.10.Final.
Now I've a lot of trouble with connection that remain open, I report some tests that I've done (the problem are on reading).
In the previous version I do three query through hibernate (and for each one i use close method on entity manager after I get the result) and them all remain in idle in transaction, then I perform a jdbi query and all hibernate sessions will disappear.
With the new version, same test, I've to increase connection pool size through
<property name="hibernate.connection.pool_size" value="3"/></properties>
but connections remain always idle in transaction and never been closed.
I've noticed that adding commit method before closing the entity manager will leave a number of connection open equals to the number that I've placed as pool size.
Can someone explains how connection works in hibernate? Especially why in the previous version connections were closed automatically after doing a jdbi query.
I have implemeted a web application using Struts2 and Hibernate 4.3.5
I am facing some problems and need some clarification on some connection pooling properties.
To make connection pooling with hibernate I have used c3p0-0.9.1.jar
Below are the connection pooling Properties of c3p0 in hibernate.cfg.xml
<!-- Connection Pooling using c3p0 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.timeout">500</property>
<property name="hibernate.c3p0.max_statements">2</property>// I heard somewhere that this property improves performance.. But dont know How it improves
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.preferredTestQuery">
select sysdate from dual;
</property>
In my application I have used * session-per-request* patterns by setting following property in hibernte-cfg.xml
<!-- To open the connection when the request hits. -->
<property name="hibernate.current_session_context_class">thread</property>
When I use this I am getting Session as following
//Here MyHiberantaeUtil is my own class having singleton pattern and Static block
// To read hibernate-cfg.xml and will create SessionFactroy object.
SessionFactory sessionFactory = MyHibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
As per the documentation .. When I use this pattern connection should be created when request is requested and should be closed when request completed.
For my case Its creating connection .. i.e I can get Session Using this getCurrentSession() But its not closing when The request ended.
To test connection pooling I have used jconsole tool in my jdk
Where I can see
`numBusyConection = 2(If that is two requests.)`
I would like to know is there any thing I missed . Why thread property is not working as expected ?
And how to say that Request has completed and request has generated ?
Is session-per-request is best pattern or better to go any other patterns ?
I did not find this class `org.hibernate.connection.C3P0ConnectionProvider` in any jar files.. But My application is connecting to DB and working fine.
Please help thanks in advance.
The JDBC connection is opened when first needed and closed when the Session is closed. You need to manually close the session when you go out of your Service layer:
session.close();
Otherwise the connections won't be closed and you'll starve the connection pool.
It's a better idea to use Spring, because it has support for automatically creating/closing sessions for you. Your MyHibernateUtil is no match for what Spring has to offer:
local transactions
global transactions
transaction annotations and automatic commit on success or rollback on runtime exceptions
Setting up Spring with Hibernate is as easy as using the HibernateUtil class.
we use Weblogic server and always set autoCommit to 'false' when getting Connection to Oracle 10g.
I want to know if there is a setting in Weblogic wherein it will automatically Commit transactions if a Commit or Rollback is not explicitly called from within application code. I heard similar setting exists in Websphere.
It looks like you are not using either Container-managed or Bean-managed transactions. Or, for that matter, you are merely retrieving a connection from a DataSource and then disabling autocommit, without the initial establishment a transaction context; this implies that you are using JDBC transactions (that rely on the transaction manager of the underlying database).
When you use Container or Bean managed transactions, you will no longer have to worry about the autocommit property of a Connection used in a transaction, as the container will ensure that the autocommit property is set to false, before returning the Connection to the application.
If you need to use Container-managed transactions, you'll need to use EJBs. Any transaction associated with an EJB will commit automatically, unless a RuntimeException or an ApplicationException is thrown.
If you need to use Bean-managed or programmatic transactions, you will have to use the UserTransaction API.
If you are using an ORM framework like Hibernate that is responsible for establishing connections, then you ought to remember that it is Hibernate that is responsible for switching off the autocommit property of the Connection. and in most cases, it would switch off the property.
If you intend to use JDBC transactions, despite the better alternative of JTA transactions, then you could attempt to set the defaultAutoCommit property for the driver, from either Admin Console, or in the JDBC configuration file of the Datasource. The snippet of the JDBC configuration file is shown below:
<?xml version='1.0' encoding='UTF-8'?>
<jdbc-data-source xmlns="http://xmlns.oracle.com/weblogic/jdbc-data-source" xmlns:sec="http://xmlns.oracle.com/weblogic/security" xmlns:wls="http://xmlns.oracle.com/weblogic/security/wls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/jdbc-data-source http://xmlns.oracle.com/weblogic/jdbc-data-source/1.0/jdbc-data-source.xsd">
<name>JDBC Data Source-Oracle</name>
<jdbc-driver-params>
<url>jdbc:oracle:thin:#localhost:1521:oracle</url>
<driver-name>oracle.jdbc.OracleDriver</driver-name>
<properties>
<property>
<name>user</name>
<value>app</value>
</property>
<!-- Disable autocommit for connections-->
<property>
<name>defaultAutoCommit</name>
<value>false</value>
</property>
</properties>
...
In the Administration Console, you may add the defaultAutoCommit=false property in the Properties textarea of the DataSource configuration:
The connections configured inside of a connection pool on the App Server are not really closed when you call the connection.close() method, they are actually returned back to the connection pool, and can be used by the next requesting object. Not sure if the DataSource connection pools will track if there are uncommitted changes on a connection being returned to the pool and perform an auto commit or rollback on it?
Setting autoCommit to false is the right thing to do.
All RDBMS that I know of commit the transaction at the end unless explicitly rolled back. Do you see a different behavior? If you suspect something is wrong, one option is to turn on logging in the database server, where you would be able to see the commit request. I am afraid I don't know how to do it in Oracle.
Logging in app server may not be useful because it too may not be issuing explicit commit
We are migrating a JDBC based application to JPA and EJB3. Our old application used the Connect#setClientInfo API to record the current user name as part of the client info:
http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html#setClientInfo%28java.lang.String,%20java.lang.String%29
We need to do something similar in the EJB3 project. How?
We can use EJB3 interceptors around the EJB service calls in order to capture the current user and set it as info on the datasource. However, I see problems with this. I think there is no guarantee when the JPA flush() occurs. If you set the client info in an interceptor, make some updates, and then return, the flush() and actual database write may not occur until well after your bean (and interceptor) are out of scope. Is this correct?
I believe JPA and EntityManagers are abstractions over the connection, and you cannot reliable set the client info on the connection. True or false?
What JPA provider are you using?
EclipseLink has support for user based connection, Oracle proxy connections and VPD. EclipseLink also defines Session and connection level events that allow you to set configuration on the JDBC connection.
See,
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing