Closed limkl-psa closed 2 months ago
Hi Christoph,
Both HHH issues were opened by me.
HHH-16062 was due to me setting query timeout to 1ms which is too low for JDBC drivers using secs. Specifying at least 1000ms resolved the issue.
HHH-18336 explores the differences in Hibernate ORM API behavior between DBMS_LOCK and long queries with large datasets.
For #3532, perhaps we could focus on whether Spring Data JPA is passing down spring.jpa.properties.jakarta.persistence.query.timeout=2000 to Hibernate and DB Drivers for the findBy/findAll methods. Custom JPA Repository methods are working, based on verification using LOCK TABLES (MySQL) and DBMS_LOCK (Oracle).
On the other hand, if this configuration is not supported for findBy/findAll and requires custom JPA Repository methods, just let me know! Thanks!
I see - thanks for opening those!
data-jpa does recognize jakarta.persistence.QueryHints
and passes them on.
The property however is part of JpaProperties
used by Spring Boot, and is passed on to the EntityManagerFactory
via LocalContainerEntityManagerFactoryBean
.
So, I do not see data-jpa involvement here right away - will check the sample you provided. Maybe we're missing something here.
I think Christoph is right. Query timeouts need to be declared on each query individually, which means that you would have to explicitly declare them on the (re)declared repository methods via @QueryHint
.
Hi Oliver, thanks for your advice. I've asked my engineering teams to rely on explicitly declared queries for now.
Interestingly, I'm able to replicate that both Hibernate 6.4.4 and EclipseLink 4.0.0 for both MySQL/Oracle DBs, do not throw QueryTimeoutException/PersistenceException for long queries exceeding the query timeout value (unlike for locked table queries).
This could explain why there is no query timeout for the Spring Data JPA findBy and findAll methods.
Update: There is no bug in Spring Data JPA / Hibernate / JDBC Drivers.
In the failing test, the JDBC statement was executed within the JDBC query timeout. The rest of the time was spent by Hibernate marshalling the ResultSet into JPA Entities, thus giving the false impression that the JDBC query timeout did not kick in.
@limkl-psa thank you for the update!
Hi Spring Data JPA Team,
Problem Statement I am trying to set spring.jpa.properties.jakarta.persistence.query.timeout in application.properties, so that JPA Repository findBy Field/All [findByName] methods would throw a QueryTimeoutException when the queries take too long. However, the query timeout does not work for them. As a result, the application thread would hang indefinitely until the long query goes through.
Setup I am using:
Non-Working Scenario
application.properties
EmployeeService.java
The long query was simulated by locking the table.
LOCK TABLES EMPLOYEE WRITE;
Working Scenarios
These scenarios are working though, throwing a jakarta.persistence.QueryTimeoutException:
For Working Scenarios #1 and #2, it is clear that Hibernate ORM, for both Criteria and Native Queries, is able to pass the value of "jakarta.persistence.query.timeout" to MySQL and Oracle JDBC Drivers to enforce the query timeout.
For Working Scenarios #3 and #4, it is clear that Spring Data JPA, for custom queries, is able to pass the value of "spring.data.jpa.jakarta.persistence.query.timeout=2000" to Hibernate ORM and then to MySQL and Oracle JDBC Drivers to enforce the query timeout.
It seems that Spring Data JPA is only unable to do so for the inferred findByField or findAll methods.
Would greatly appreciate any help/advice on this.
Thanks!