Moving from Spring Boot 2 to Spring Boot 3 forces a move from Hibernate 5 to Hibernate 6.
We have an application that uses a dynamically constructed CriteriaQuery to display data in a UI, but then to allow download of the data we make use of PostgreSQL UNLOAD command to send the data to an AWS S3 bucket. The generation of the UNLOAD commands requires the translation of the CriteraQuery to String representing the corresponding SQL SELECT statement.
The translation is currently being done with the getQueryMethod() after unwrapping the TypedQuery. A direct replacement seems to be missing, does anyone know how this might be accomplished within Hibernate 6?
This is not so easy. A CriteriaQuery or HQL query could be split into multiple separate queries (polymorphic query). The final SQL might depend on parameter values when e.g. parameters are used in a context that doesn’t allow untyped expressions and the parameter type is unknown.
So if you want to get your hands on the SQL with ORM 6, you will have to do what ORM 6 does internally and translate the query. Take a look into org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan which is the entry point for that whole translation process. You need to get your hands onto a JdbcOperationQuerySelect which has a getSqlString() method.
I also used the getQueryString() and miss it now.
It was used just for writing tests and validating that the Query build by Criteria Api is correct but still very useful.
You can use org.hibernate.resource.jdbc.spi.StatementInspector to get a callback when statements are executed. Store that into a ThreadLocal<List<String>> and then you can check what SQL queries were executed.
The org.hibernate.resource.jdbc.spi.StatementInspector would not work in my case. The application handles an incoming request by creating the CriteriaQuery but then branches based upon the expected output. For a normal result the query is executed and the result translated to JSON for the response. There is another output option where the output is sent to an AWS S3 bucket. This is done by wrapping the text of the SQL query statement inside and UNLOAD function along with the target parameters. Do this feature in the application we cannot migrate to Hibernate v6 without an entire rewrite of the application.
Please create a new topic and share some more details about this use case. I have no idea what this unload call looks like or what you need, but maybe there is a way to get this working.
Should the org.hibernate.resource.jdbc.spi.StatementInspector be called for statments from the critria api? Because in my case it I was not able to see that - it was only called for normal statements.
About your other suggestion: If I would find the needed information somewhere in org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan, how would I get the org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan object?
Yes, StatementInspector is called for all statements. You can construct a ConcreteSqmSelectQueryPlan similar to how org.hibernate.query.sqm.internal.QuerySqmImpl#resolveSelectQueryPlan does it.