| While using the YourKit performance monitoring tool I found a hotspot in file hibernate-core/5.2.18-SNAPSHOT\hibernate-core-5.2.18-20180621.012308-7-sources.jar!\org\hibernate\engine\loading\internal\LoadContexts.javafunction register(Statement statement, boolean cancelable) lines due to time spent inside Object.hashCode():
context = collectionLoadContexts.get(resultSet);
The problem here is that the ResultSet object (which in our particular case is a HikariProxyResultSet@784246943 wrapping SQLServerResultSet:27 wrapping a com.sun.proxy$Proxy247 wrapping an org.hibernate.engine.jdbc.ResultSetWrapper wrapping a com.zaxxer.hikari.pool.HikariProxyResultSet wrapping a microsoft.sqlserver.jdbc.SQLServerResultSet) is large and has a lot of fields, some of which seem to be to do with current status rather than identity, which could cause cache misses in the collectionLoadContexts hash, and this makes it slow to hash. If possible, it would be much more efficient to override the default behavior of .hashCode() and .equals() for implementations of ResultSet to only take into account fields that describe identity, rather than current status. In particular, if an implementation of Statement already has a functional unique identifier, both .hashCode() and .equals() should depend just on that. (In our particular case, resultSet.h.rs.delegate.traceID and resultSet.h.rs.connection.delegate.traceID look like they might be unique identifiers.) I understand that handling this correctly might require work from the HikariCP connection pool and/or the Microsoft JDBC driver code as well as or instead of from Hibernate. |