Hibernates' slow sql queries in Websphere Liberty

Viewed 155

I'm deploying an EAR to Websphere Liberty 21.0.0.6 with persistence provider Hibernate 5.4 (my problem persists in version 5.5). Database is Oracle 12c.

I activated Hibernate's feature of logging slow sql queries via persistence.xml (https://docs.jboss.org/hibernate/orm/5.5/javadocs/org/hibernate/cfg/AvailableSettings.html#LOG_SLOW_QUERY) The setting is working, but unfortunately, Liberty has a prepared statement wrapper that has no sensible toString() method. So the output in my logs is

org.hibernate.SQL_SLOW: SlowQuery: 3299 milliseconds. SQL: 'com.ibm.ws.rsadapter.jdbc.v42.WsJdbc42PreparedStatement@229da89'
org.hibernate.SQL_SLOW: SlowQuery: 2230 milliseconds. SQL: 'com.ibm.ws.rsadapter.jdbc.v42.WsJdbc42PreparedStatement@90069551'

and so on. Which doesn't help much in figuring out which queries are slow... Seems so that Hibernate just does a toString() on the prepared statement. See the source of org.hibernate.engine.jdbc.spi.SqlStatementLogger#logSlowQuery(Statement, long).

  • Is there a possibility to configure hibernate or liberty to output the real SQL? Do I have to implement an own statement wrapper?
  • Should I open a bug in hibernate?
2 Answers

Yes, you should open a bug against Hibernate for this. The assertion that PreparedStatement.toString will show the SQL is incorrect because there is no requirement within the JDBC specification or PreparedStatement JavaDoc that would guarantee or even recommend that behavior. The toString output that you see is pretty standard, following java.lang.Object.toString conventions of fully qualified class name @ hexadecimal hash code.

WebSphere Application Server Liberty does have some options that can help you see the SQL queries and other JDBC operations. See the following section on enabling JDBC driver trace, which goes into detail depending on which database/JDBC driver you are using:

https://www.ibm.com/docs/en/was-liberty/nd?topic=liberty-enabling-jdbc-tracing

I now solved it via a custom ServiceContributor (referred to in META-INF/services/...) where I override the JdbcServicesInitiator and there, in turn, I override JdbcServicesImpl#configure to set a custom SqlStatementLogger.

In there, I use a method from the WSJdbcUtil class to refind the sql from the statement. Of course, I first need to load the class from an appropriate class loader (the one of the statement)... ugly but works.

Related