Hi Spring 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: 1. SpringBoot 3.2.4 2. Hibernate 6.4.4 (pulled in by spring-boot-starter-data-jpa:3.2.4) 3. Java 17.0.11 4. Oracle19.23 DB 5. MySQL 8 DB
application.properties
# Query Timeout (must be set in multiples of 1000ms as JDBC specs require it in secs)
spring.jpa.properties.jakarta.persistence.query.timeout=2000
EmployeeService.java
@Service
public class EmployeeService {
private final EmployeeRepository employeeRepository;
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public Employee[] getAllEmployees()
{
Employee[] employees = employeeRepository.findAll().toArray(new Employee[0]);
return employees;
}
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:
- Calling an explicitly defined @Query method without a @QueryHint in the JPA Repository.
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Query(value = "select e from Employee e")
List<Employee> findAllEmployees();
}
- Calling Hibernate's CriteriaQuery with an query hint for jakarta.persistence.query.timeout=2000 (must be units of 1000ms)
@Test
public void criteriaQueryTimeoutShouldThrowQueryTimeoutException() throws Exception {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
cq.select(root);
TypedQuery<Employee> query = em.createQuery(cq);
query.setHint("jakarta.persistence.query.timeout", 2000); // Very low timeout to force the exception
assertThrows(QueryTimeoutException.class, query::getResultList);
}
Would greatly appreciate any help/advice on this.
Thanks!
Comment From: wilkinsona
This sort of low-level interaction with JPA/Hibernate is handled by Spring Data JPA which is managed as a separate project. Please open an issue over there so that the Data JPA team can investigate.
Comment From: limkl-psa
Raised here: https://github.com/spring-projects/spring-data-jpa/issues/3532