spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
2.92k stars 1.39k forks source link

After upgrading from Spring Boot 2.7.5 to 3.2.5, stored procedure calls treat named parameters as positional parameters. #3513

Closed MANIKUMAR98 closed 1 week ago

MANIKUMAR98 commented 1 week ago

In earlier version of Spring Boot 2.7, parameters were treated as named parameters, allowing flexibility in their order. However, after upgrading to Spring Boot version 3.2.5, parameters are now treated as positional parameters, requiring adherence to their specified order. I want it to behave as named parameter itself. Below is the detailed description of code.

Spring boot version- 3.2.5 Database- Microsoft SQL server

Dependencies using:

<dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

Creating connection:

  public HikariDataSource primaryDataSource() {    
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(driverClassName);
        hikariConfig.setJdbcUrl(url);
        hikariConfig.setUsername(username);
        hikariConfig.setPassword(password);
        hikariConfig.setMaximumPoolSize(maximumPoolSize);
        hikariConfig.setConnectionTimeout(connectionTimeout);
        hikariConfig.setIdleTimeout(idleTimeout);
        hikariConfig.setMinimumIdle(minimumIdle);
        hikariConfig.setPoolName(poolName);

        hikariConfig.addDataSourceProperty("useUnicode", "false");
        HikariDataSource ds = new HikariDataSource(hikariConfig);
        return ds;
    }

    public EntityManagerFactory entityManagerFactory( HikariDataSource readingDatasource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(datasource);
        em.setPackagesToScan("com.example.com");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        em.afterPropertiesSet();
        return em.getObject();
    }

Calling database using entity manager:

public List<String> getData(LocalDateTime startTime, LocalDateTime endTime) {
        List<String> result = new ArrayList<>();
        EntityManager entityManager = null;
        StoredProcedureQuery storedProcedure = null;
        try {

            entityManager = entityManagerFactory.createEntityManager();
            storedProcedure = entityManager.createStoredProcedureQuery(procedure)

                    .registerStoredProcedureParameter("FromTime", LocalDateTime.class,
                            ParameterMode.IN)
                                        .registerStoredProcedureParameter("ToTime", LocalDateTime.class,
                            ParameterMode.IN)
                    .registerStoredProcedureParameter(Constants.RESPONSECODE, String.class, ParameterMode.OUT)
                    .registerStoredProcedureParameter(Constants.STATUSMESSAGE, String.class, ParameterMode.OUT)
                    .setParameter("FromTime", startTime)
                    .setParameter("ToTime", endTime);
            storedProcedure.execute();
            @SuppressWarnings("unchecked")
            List<Object> list = storedProcedure.getResultList();
        } catch (Exception e) {
            log.error("Exception occurred - {}", e.getMessage(), e);
        } finally {
            closeResources(entityManager);
        }
        return result;
    }

FYI, all imports previously from javax had to be changed to jakarta in Spring Boot 3

christophstrobl commented 1 week ago

Thank you for reporting the issue. The provided snippet is using plain JPA without any Spring Data involvement. So it is very likely that you've hit an issue with the underlying persistence provider. Please report the issue to the Hibernate Team for further investigation. It would be great if you could leave a comment on this issue linking to the hibernate one for others to find. Thank you!