Skip to content

Spring Data JPA add support to Set-returning Functions in from Clause #3864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
oscarfanchin opened this issue Apr 30, 2025 · 0 comments
Open
Labels
status: waiting-for-triage An issue we've not yet triaged

Comments

@oscarfanchin
Copy link

Spring Data JPA add support to Set-returning Functions in from Clause

Context

This test suite test suite demonstrates the current behavior of Spring Data JPA when handling SQL set-returning functions (SRF) in the FROM clause, as described in the Hibernate ORM documentation. While such queries work correctly when executed directly via Hibernate (e.g., through EntityManager) or declared with @NativeQuery, they currently cause a BeanCreationException when used in a Spring Data JPA repository method.

This does not necessarily indicate a limitation, but rather that support for this pattern may not yet have been considered or integrated into the Spring Data JPA query parser. This document can serve as a reference for evaluating the possibility of supporting this usage in future versions.

Spring Boot Versions

We test the same codebase using different POM files to control the Spring Boot version:

  • Spring Boot 3.4.5: default execution (no -f parameter).
  • Spring Boot 3.5.0-RC1: executed with -f pom350RC1.xml.
  • Spring Boot 4.0.0-SNAPSHOT: executed with -f pom400SNAP.xml.

Hibernate

All examples use Hibernate 7.0.0.CR1 and JPA 3.2.

Function Mapping

The PostgreSQL set-returning function is mapped using a custom FunctionContributor, allowing us to call:

select d.id, d.name from get_department_function(:date) d

The mapped function returns a result set that can be queried via JPQL.


Repository Tests

1. DepartmentSpringDataRepositorySimpleTest

@Test
void testFindAllDepartments() {
    List<Department> departments = springDataRepository.findAll();
    ...
}
  • A basic findAll() test using Spring Data JPA.
@Test
void testFindDepartementsNativeFunctionCall() {
    List<DepartmentInterfaceProjection> departments = springDataRepository.findAllDepartments(LocalDate.now());
    ...
}
  • A native query test using @NativeQuery, introduced in Spring Data 3.2.
@NativeQuery(value = "select d.id, d.name from get_department_function(:date) d")
List<DepartmentInterfaceProjection> findAllDepartments(@Param("date") LocalDate date);

2. DepartmentManualRepositoryTest

@Test
void testFindAllDepartmentsHibernateDirect() {
    List<DepartmentDto> departments = manualRepository.findAllDepartments(LocalDate.now());
    ...
}
  • Executes the same set-returning function query using Hibernate directly via EntityManager.
@Repository
public class DepartmentManualRepository {
    ...
    public List<DepartmentDto> findAllDepartments(LocalDate date) {
        return entityManager.createQuery(
            QueryConstants.QUERY_SET_RETURN_FUNCTION,
            DepartmentDto.class
        ).setParameter("date", date).getResultList();
    }
}

3. DepartmentSpringDataRepositoryTest

@Test
void testThatContextFailsToStartDueToInvalidQuery() {
    assertThrows(BeanCreationException.class, () -> {
        new SpringApplicationBuilder(DepartmentTestApplication.class)
            .properties("test.broken-query.enabled=true").run();
    });
}
  • This test demonstrates that Spring Data's parser currently fails to parse a query using a set-returning function in the from clause.
  • The same query works perfectly via EntityManager.

Query Constants

public class QueryConstants {
    public static final String QUERY_SET_RETURN_FUNCTION = 
        "select new com.example.departmenttest.dto.DepartmentDto(d.id, d.name) " +
        "from getDepartementFunction(:date) d";
}

Summary

  • Spring Data @NativeQuery supports set-returning functions with direct native SQL.
  • Hibernate with EntityManager fully supports from get_department_function(:date).
  • Spring Data JPQL parsing currently does not support this feature (BeanCreationException).

See also: Hibernate 7 User Guide - Set-returning functions

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 30, 2025
oscarfanchin added a commit to oscarfanchin/spring-data-jpa that referenced this issue May 2, 2025
oscarfanchin added a commit to oscarfanchin/spring-data-jpa that referenced this issue May 2, 2025
… in HQL parser and query rendering for H7

Signed-off-by: oscarfanchin <oscar.fanchin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

2 participants