It would be nice to support Oracle UCP pooling. The reason for it is that Oracle is in very widespread use in enterprise environments. UCP is the preferred way to pooling with Oracle (the built-in pooling in the driver is deprecated). UCP adds additional enterprise-grade capabilities, such as support for ONS (Oracle Notification Service), FCF (Fast Connection Failover), enhanced JMX-introspection, RAC support etc.

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/jjucp/intro.html#GUID-8CF6555B-E7EA-462C-88C8-78678E43BD17

But given the comments in: https://github.com/spring-projects/spring-boot/issues/8700 this might not be acceptable, as I guess access to the Oracle Maven repo would be required (if not dealing with it all through reflection, which is not ideal).

WDYT?

If not directly in spring boot due to the above challenge with repos, would https://projects.spring.io/spring-data-jdbc-ext/ be a better place? But I do not see any specific boot support in spring-data - and also the project does not seem very active with releases etc.

Boot is used a lot in enterprise envs, and supporting enterprise requirements and best-practice patterns in the framework seems sane to me.

Comment From: wilkinsona

I guess access to the Oracle Maven repo would be required

Yes, I think it would and that's not something that we want Spring Boot's build to rely upon. Spring Data JDBC extensions would certainly be a better place than Spring Boot for this functionality, although I'm not sure that it's the right place. Perhaps @trisberg can offer some guidance?

Comment From: fabio-grassi-gbs

Oracle JDBC drivers have been added to Maven Central as described in this blog.

I kindly suggest to consider reopening this issue and implement it.

Comment From: wilkinsona

Good point, @fabio-grassi-gbs. No promises at this point, but I'm going to re-open this so that we can take another look at what it would entail now that the Maven Central issue is no longer a problem.

Comment From: wilkinsona

UCP's license is unusual (Oracle Free Use Terms and Conditions (FUTC)). It's unclear to me whether open source usage is permitted and whether or not it's compatible with Apache V2. We can't proceed here until this has been clarified.

Comment From: wilkinsona

Legal have looked at the licence and are happy for us to proceed.

Comment From: fabio-grassi-gbs

Great, thanks. I'll be glad to test it as soon as available.

Comment From: davidkarlsen

Anything we can do to help out here @wilkinsona ?

Comment From: wilkinsona

@davidkarlsen Thanks for the offer. If you have experience with using and configuring UCP, then I'm almost certain that you can help. Perhaps you could share how you typically configure UCP in a Spring Boot application and we can then see how that might fit with our existing DataSource auto-configuration and configuration properties?

Comment From: davidkarlsen

See below code for typical config. I also have an implementation of DataSourcePoolMetadata for UCP which I could offer.

package com.org.somepackage

import java.sql.SQLException
import javax.annotation.PreDestroy
import javax.sql.DataSource
import oracle.jdbc.pool.OracleDataSource
import oracle.ucp.UniversalConnectionPoolException
import oracle.ucp.admin.UniversalConnectionPoolManagerImpl
import oracle.ucp.jdbc.PoolDataSourceFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.transaction.PlatformTransactionManager

@Configuration
@EnableConfigurationProperties(DataSourceConfigProperties::class)
class DataSourceConfig {

    // Do *NOT* use SQLForValidateConnection - bad for performance, Oracle has build in mech instead:
    // https://docs.oracle.com/database/121/JJUCP/connect.htm#JJUCP8136

    @PreDestroy
    @Throws(UniversalConnectionPoolException::class)
    fun shutdown() {
        for (poolName in UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager()
                .connectionPoolNames) {
            UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager()
                    .destroyConnectionPool(poolName)
        }
    }

    @Bean
    @Throws(SQLException::class, UniversalConnectionPoolException::class)
    fun dataSource(dataSourceConfigProperties: DataSourceConfigProperties): DataSource {
        shutdown() // needed after 12.0.2 - bug or feature - nevertheless...

        val poolDataSource = PoolDataSourceFactory.getPoolDataSource()
        poolDataSource.connectionPoolName = "SOMEUNIQUEPOOLNAME"
        poolDataSource.connectionFactoryClassName = OracleDataSource::class.java.name
        poolDataSource.minPoolSize = dataSourceConfigProperties.minPoolSize
        poolDataSource.maxPoolSize = dataSourceConfigProperties.maxPoolSize
        poolDataSource.initialPoolSize = dataSourceConfigProperties.initialPoolSize
        poolDataSource.validateConnectionOnBorrow = dataSourceConfigProperties.validateConnectionOnBorrow
        poolDataSource.maxConnectionReuseTime = dataSourceConfigProperties.maxConnectionReuseTimeSec
        poolDataSource.inactiveConnectionTimeout = dataSourceConfigProperties.inactiveConnectionTimeoutSec
        poolDataSource.abandonedConnectionTimeout = dataSourceConfigProperties.abandonedConnectionTimeout
        poolDataSource.timeToLiveConnectionTimeout = dataSourceConfigProperties.timeToLiveConnectionTimeout
        poolDataSource.connectionWaitTimeout = dataSourceConfigProperties.connectionWaitTimeout
        poolDataSource.onsConfiguration = dataSourceConfigProperties.onsConfiguration
        poolDataSource.fastConnectionFailoverEnabled = dataSourceConfigProperties.fastConnectionFailoverEnabled
        poolDataSource.maxStatements = dataSourceConfigProperties.maxStatements

        poolDataSource.url = dataSourceConfigProperties.url
        poolDataSource.user = dataSourceConfigProperties.user
        poolDataSource.password = dataSourceConfigProperties.password
        poolDataSource.loginTimeout = dataSourceConfigProperties.loginTimeout
        poolDataSource.connectionProperties = dataSourceConfigProperties.connectionProperties

        return poolDataSource
    }

    @Bean
    @Primary
    @ConfigurationProperties("transaction-manager")
    fun transactionManager(dataSource: DataSource): PlatformTransactionManager {
        return DataSourceTransactionManager(dataSource)
    }
}

Comment From: wschlich

If not directly in spring boot due to the above challenge with repos, would https://projects.spring.io/spring-data-jdbc-ext/ be a better place? But I do not see any specific boot support in spring-data - and also the project does not seem very active with releases etc.

It seems spring-data-jdbc-ext is dead. Citing https://github.com/spring-projects/spring-data-jdbc-ext

NOTICE: This project has been archived as of March 27th, 2019. There will be no maintenance or new development going forward.

Does anyone know whether the functionality implemented by the RacRetryOperationsInterceptor + RacFailoverRetryPolicy is implemented elsewhere now?

https://github.com/spring-projects/spring-data-jdbc-ext/tree/master/spring-data-oracle/src/main/java/org/springframework/data/jdbc/retry/oracle

We'd like to use Oracle UCP + RAC Fast Connection Failover (FCF) with Spring Data JPA (not with Spring Boot, I have to admit -- I just found this issue while researching).

Comment From: davidkarlsen

@wilkinsona any comments?

Comment From: wilkinsona

@davidkarlsen Thanks for your patience and for the configuration example. The configuration looks like quite a good fit for Spring Boot's existing spring.datasource.* properties for things like the URL, username, and password. We'd then have UCP-specific properties (spring.datasource.ucp or perhaps spring.datasource.oracleucp) that are bound to the PooledDataSource instance.

Comment From: snicoll

Closing in favour of PR #23403