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:

  1. 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();
}
  1. 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