On commit, Hibernate reopens and closes additional connection
Description
Activity
Show:
Olivier G November 16, 2020 at 3:23 PM
I'm a bit late here but I bumped into this problem recently and the commit for this issue is on version 5.3.0 (version 5.2.13 mentioned there still has this issue).
Fixed
Assignee
Unassigned
UnassignedReporter
Alon
AlonComponents
Fix versions
Affects versions
Priority
Created January 3, 2018 at 2:30 AM
Updated November 16, 2020 at 3:59 PM
Resolved January 9, 2018 at 4:21 PM
When running in standalone (non JEE) environment with the default Hibernate configuration, I'm seeing this behavior regarding Hibernate's use of underlying DataSource's connections:
commit() will commit and close the JDBC connection, then it will reopen it, set it to autocommit false and close it immediately.
I instrumented DataSource and Connection classes to print when their methods are called.
Here is the full code:
package hibernate1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.util.List; import javax.sql.DataSource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.dialect.MySQLDialect; import com.mysql.cj.jdbc.MysqlDataSource; public class Hibernate1 { private static DataSource initDataSource() { MysqlDataSource ds = new MysqlDataSource(); ds.setUrl("jdbc:mysql://localhost:3306/db1"); ds.setUser("root"); ds.setPassword("password"); return ds; } private static DataSource instrumentDataSource(final DataSource ds) { return (DataSource) Proxy.newProxyInstance(Hibernate1.class.getClassLoader(), new Class[] { DataSource.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("::" + method.getName()); if (!method.getName().equals("getConnection")) { return method.invoke(ds, args); } else { final Connection c = (Connection) method.invoke(ds, args); return (Connection) Proxy.newProxyInstance(Hibernate1.class.getClassLoader(), new Class[] { Connection.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(":::" + method.getName()); return method.invoke(c, args); }}); } } }); } private static SessionFactory initHibernate(DataSource ds) { StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() .applySetting("hibernate.connection.datasource", ds) .build(); Metadata metadata = new MetadataSources(standardRegistry) .addAnnotatedClass( User.class ) .getMetadataBuilder() .build(); return metadata.getSessionFactoryBuilder().build(); } public static void main(String[] args) throws Exception { DataSource ds = instrumentDataSource(initDataSource()); SessionFactory sf = initHibernate(ds); Session session0 = sf.openSession(); System.out.println("# before begin()"); session0.getTransaction().begin(); System.out.println("# after begin()"); List result = session0.createQuery("from User").getResultList(); System.out.println("# before commit()"); session0.getTransaction().commit(); System.out.println("# after commit()"); session0.close(); } }
And here is the full output:
Jan 02, 2018 5:33:04 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core {5.2.12.Final} Jan 02, 2018 5:33:04 PM org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found Jan 02, 2018 5:33:04 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final} ::getConnection :::getMetaData :::getMetaData Jan 02, 2018 5:33:04 PM org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect :::close # before begin() ::getConnection :::getAutoCommit :::setAutoCommit # after begin() Jan 02, 2018 5:33:05 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService INFO: HHH000397: Using ASTQueryTranslatorFactory :::prepareStatement # before commit() :::commit :::isClosed :::clearWarnings :::close ::getConnection :::setAutoCommit :::isClosed :::clearWarnings :::close # after commit()