diff --git a/buildSrc/src/main/groovy/io.micronaut.build.internal.sql-module.gradle b/buildSrc/src/main/groovy/io.micronaut.build.internal.sql-module.gradle index bbfa78fc7..60ed265fe 100644 --- a/buildSrc/src/main/groovy/io.micronaut.build.internal.sql-module.gradle +++ b/buildSrc/src/main/groovy/io.micronaut.build.internal.sql-module.gradle @@ -2,9 +2,3 @@ plugins { id 'io.micronaut.build.internal.module' id 'io.micronaut.build.internal.sql-base' } - -configurations.all { - resolutionStrategy { - force 'org.graalvm.sdk:graal-sdk:22.3.2' - } -} diff --git a/hibernate-jpa-spring/build.gradle b/hibernate-jpa-spring/build.gradle deleted file mode 100644 index 50db5de9a..000000000 --- a/hibernate-jpa-spring/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -plugins { - id 'io.micronaut.build.internal.sql-module' -} - -dependencies { - annotationProcessor(mn.micronaut.graal) - - api(libs.managed.hibernate.core) { - exclude group:'org.javassist', module:'javassist' - } - - api(mn.micronaut.aop) - api projects.micronautHibernateJpa - - api projects.micronautJdbc - api(mnSpring.micronaut.spring) - api(mnSpring.spring.orm) -} diff --git a/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/HibernateTransactionManagerFactory.java b/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/HibernateTransactionManagerFactory.java deleted file mode 100644 index 2de0d301e..000000000 --- a/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/HibernateTransactionManagerFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.configuration.hibernate.jpa.spring; - -import io.micronaut.context.annotation.*; -import io.micronaut.jdbc.spring.DataSourceTransactionManagerFactory; -import org.hibernate.SessionFactory; -import org.springframework.orm.hibernate5.HibernateTransactionManager; - -import javax.sql.DataSource; - -/** - * Sets up the default hibernate transaction manager. - * - * @author graemerocher - * @since 1.0 - */ -@Factory -@Requires(classes = HibernateTransactionManager.class) -@Replaces(factory = DataSourceTransactionManagerFactory.class) -public class HibernateTransactionManagerFactory { - - /** - * @param sessionFactory The {@link SessionFactory} - * @param dataSource The {@link DataSource} - * @return The {@link HibernateTransactionManager} - */ - @Bean - @Requires(classes = HibernateTransactionManager.class) - @EachBean(SessionFactory.class) - HibernateTransactionManager hibernateTransactionManager(SessionFactory sessionFactory, @Parameter DataSource dataSource) { - HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager(sessionFactory); - hibernateTransactionManager.setDataSource(dataSource); - return hibernateTransactionManager; - } -} diff --git a/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/SpringHibernateCurrentSessionContextClassProvider.java b/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/SpringHibernateCurrentSessionContextClassProvider.java deleted file mode 100644 index c37538b16..000000000 --- a/hibernate-jpa-spring/src/main/java/io/micronaut/configuration/hibernate/jpa/spring/SpringHibernateCurrentSessionContextClassProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.configuration.hibernate.jpa.spring; - -import io.micronaut.configuration.hibernate.jpa.HibernateCurrentSessionContextClassProvider; -import jakarta.inject.Singleton; -import org.hibernate.context.spi.CurrentSessionContext; -import org.springframework.orm.hibernate5.SpringSessionContext; - -/** - * Spring integration implementation of {@link HibernateCurrentSessionContextClassProvider}. - * - * @author Denis Stepanov - * @since 3.3.2 - */ -@Singleton -public class SpringHibernateCurrentSessionContextClassProvider implements HibernateCurrentSessionContextClassProvider { - - /** - * @return SpringSessionContext - */ - @Override - public Class get() { - return SpringSessionContext.class; - } - -} diff --git a/hibernate-jpa/src/test/resources/logback.xml b/hibernate-jpa/src/test/resources/logback.xml index 47706284e..655f0123f 100644 --- a/hibernate-jpa/src/test/resources/logback.xml +++ b/hibernate-jpa/src/test/resources/logback.xml @@ -11,5 +11,4 @@ - diff --git a/hibernate-reactive/src/test/resources/logback.xml b/hibernate-reactive/src/test/resources/logback.xml index e7ec54e2f..655f0123f 100644 --- a/hibernate-reactive/src/test/resources/logback.xml +++ b/hibernate-reactive/src/test/resources/logback.xml @@ -11,5 +11,4 @@ - - \ No newline at end of file + diff --git a/jdbc-dbcp/build.gradle b/jdbc-dbcp/build.gradle index 77b8382d4..0e27b68c6 100644 --- a/jdbc-dbcp/build.gradle +++ b/jdbc-dbcp/build.gradle @@ -11,13 +11,9 @@ dependencies { testRuntimeOnly(libs.managed.h2) testAnnotationProcessor(mn.micronaut.inject.java) - testAnnotationProcessor(mnSpring.micronaut.spring.annotation) - testImplementation(mnSpring.micronaut.spring) testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mn.micronaut.management) testImplementation(mnMicrometer.micronaut.micrometer.core) testImplementation(mnCache.micronaut.cache.core) - - testImplementation(mnSpring.spring.jdbc) } diff --git a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/BookService.java b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/BookService.java index 1ede19d05..9fc6a98c3 100644 --- a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/BookService.java +++ b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/BookService.java @@ -17,7 +17,6 @@ import jakarta.inject.Named; import jakarta.inject.Singleton; -import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.sql.Connection; @@ -48,27 +47,34 @@ public BookService(DataSource dataSource, @Named("secondary") DataSource seconda } } - @Transactional public String save(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); + connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } - @Transactional public String longsave(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); + connection.createStatement().execute("UPDATE foo SET id = id + 1;"); Thread.sleep(10); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + + connection.commit(); + return Integer.toString(value); } catch (InterruptedException e) { e.printStackTrace(); @@ -76,17 +82,19 @@ public String longsave(String title) throws SQLException { return ""; } - - @Transactional("secondary") public String saveTwo(String title) throws SQLException { try (Connection connection = secondary.getConnection()) { + connection.setAutoCommit(false); + connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } -} \ No newline at end of file +} diff --git a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceConfigurationSpec.groovy b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceConfigurationSpec.groovy index 25c4fd240..b8183b3aa 100644 --- a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceConfigurationSpec.groovy +++ b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceConfigurationSpec.groovy @@ -15,12 +15,12 @@ */ package io.micronaut.configuration.jdbc.dbcp +import io.micronaut.jdbc.DataSourceResolver import org.apache.commons.dbcp2.BasicDataSource import io.micronaut.context.ApplicationContext import io.micronaut.context.DefaultApplicationContext import io.micronaut.context.env.MapPropertySource import io.micronaut.inject.qualifiers.Qualifiers -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy import spock.lang.Specification import javax.sql.DataSource @@ -49,13 +49,14 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(BasicDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - BasicDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource as BasicDataSource + BasicDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.url == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -76,13 +77,14 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(BasicDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - BasicDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource as BasicDataSource + BasicDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) as BasicDataSource ResultSet resultSet = dataSource.getConnection().prepareStatement("SELECT H2VERSION() FROM DUAL").executeQuery() resultSet.next() String version = resultSet.getString(1) @@ -105,13 +107,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.default.defaultCatalog': 'catalog'] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(BasicDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - BasicDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource as BasicDataSource + BasicDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: dataSource.maxWaitMillis == 5000 @@ -133,13 +136,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.foo': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(BasicDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - BasicDataSource dataSource = (applicationContext.getBean(DataSource, Qualifiers.byName("foo")) as TransactionAwareDataSourceProxy).targetDataSource + BasicDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("foo"))) then: //The default configuration is supplied because H2 is on the classpath dataSource.url == 'jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' diff --git a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceFactorySpec.groovy b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceFactorySpec.groovy index a4f5ce28f..3bae0c532 100644 --- a/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceFactorySpec.groovy +++ b/jdbc-dbcp/src/test/groovy/io/micronaut/configuration/jdbc/dbcp/DatasourceFactorySpec.groovy @@ -15,23 +15,23 @@ */ package io.micronaut.configuration.jdbc.dbcp -import io.micronaut.jdbc.spring.SpringDataSourceResolver +import io.micronaut.jdbc.DataSourceResolver import org.apache.commons.dbcp2.BasicDataSource -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy import spock.lang.Specification -class DatasourceFactorySpec extends Specification { - - DatasourceFactory datasourceFactory +import javax.sql.DataSource - def setup() { - datasourceFactory = new DatasourceFactory(new SpringDataSourceResolver()) - } +class DatasourceFactorySpec extends Specification { def "create basic datasource"() { given: def dataSource = new BasicDataSource(validationQuery: "SELECT 1") - + DatasourceFactory datasourceFactory = new DatasourceFactory(new DataSourceResolver() { + @Override + DataSource resolve(DataSource ds) { + return ds + } + }) when: def metadata = datasourceFactory.dbcpDataSourcePoolMetadata(dataSource) @@ -44,13 +44,23 @@ class DatasourceFactorySpec extends Specification { metadata.usage >= 0 } - def "create transactional datasource"() { + def "create proxy datasource"() { given: def dataSource = new BasicDataSource(validationQuery: "SELECT 1") - def transactionalDataSource = new TransactionAwareDataSourceProxy(targetDataSource: dataSource) + def proxyDataSource = Spy(dataSource) + def dataSourceResolver = new DataSourceResolver() { + @Override + DataSource resolve(DataSource ds) { + if (ds.is(proxyDataSource)) { + return dataSource + } + return ds + } + } + DatasourceFactory datasourceFactory = new DatasourceFactory(dataSourceResolver) when: - def metadata = datasourceFactory.dbcpDataSourcePoolMetadata(transactionalDataSource) + def metadata = datasourceFactory.dbcpDataSourcePoolMetadata(proxyDataSource) then: metadata diff --git a/jdbc-hikari/build.gradle b/jdbc-hikari/build.gradle index e0ecb9f5f..52ce9ef3d 100644 --- a/jdbc-hikari/build.gradle +++ b/jdbc-hikari/build.gradle @@ -13,13 +13,10 @@ dependencies { testRuntimeOnly(libs.managed.h2) testAnnotationProcessor(mn.micronaut.inject.java) - testImplementation(mnSpring.micronaut.spring) testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mn.micronaut.management) testImplementation(mnMicrometer.micronaut.micrometer.core) testImplementation(mnCache.micronaut.cache.core) - - testImplementation(mnSpring.spring.jdbc) } diff --git a/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/BookService.java b/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/BookService.java index d0036b7f0..1419b6c41 100644 --- a/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/BookService.java +++ b/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/BookService.java @@ -17,7 +17,6 @@ import jakarta.inject.Named; import jakarta.inject.Singleton; -import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.sql.Connection; @@ -48,27 +47,32 @@ public BookService(DataSource dataSource, @Named("secondary") DataSource seconda } } - @Transactional public String save(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } - @Transactional public String longsave(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); Thread.sleep(10); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + + connection.commit(); + return Integer.toString(value); } catch (InterruptedException e) { e.printStackTrace(); @@ -77,16 +81,18 @@ public String longsave(String title) throws SQLException { } - @Transactional("secondary") public String saveTwo(String title) throws SQLException { try (Connection connection = secondary.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } -} \ No newline at end of file +} diff --git a/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/DatasourceConfigurationSpec.groovy b/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/DatasourceConfigurationSpec.groovy index f7d3e88c6..585632533 100644 --- a/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/DatasourceConfigurationSpec.groovy +++ b/jdbc-hikari/src/test/groovy/io/micronaut/configuration/jdbc/hikari/DatasourceConfigurationSpec.groovy @@ -21,6 +21,7 @@ import io.micronaut.context.ApplicationContext import io.micronaut.context.DefaultApplicationContext import io.micronaut.context.env.MapPropertySource import io.micronaut.inject.qualifiers.Qualifiers +import io.micronaut.jdbc.DataSourceResolver import io.micronaut.jdbc.metadata.DataSourcePoolMetadata import spock.lang.Specification @@ -54,13 +55,14 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - HikariUrlDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariUrlDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.jdbcUrl == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -81,13 +83,14 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - HikariDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) ResultSet resultSet = dataSource.getConnection().prepareStatement("SELECT H2VERSION() FROM DUAL").executeQuery() resultSet.next() String version = resultSet.getString(1) @@ -114,13 +117,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.default.validationQuery' : 'select 3'] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - HikariDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: dataSource.connectionTimeout == 500 @@ -145,13 +149,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.foo' : [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - HikariDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.jdbcUrl == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -160,7 +165,7 @@ class DatasourceConfigurationSpec extends Specification { dataSource.driverClassName == 'org.h2.Driver' when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("foo")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("foo"))) then: //The default configuration is supplied because H2 is on the classpath dataSource.jdbcUrl == 'jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -182,13 +187,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.foo' : [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.getBeansOfType(DataSource).size() == 2 applicationContext.getBeansOfType(DatasourceConfiguration).size() == 2 when: - dataSource = (HikariDataSource) applicationContext.getBean(DataSource, Qualifiers.byName("default")).targetDataSource + dataSource = (HikariDataSource) dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("default"))) then: dataSource.jdbcUrl == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -197,7 +203,7 @@ class DatasourceConfigurationSpec extends Specification { dataSource.driverClassName == 'org.h2.Driver' when: - dataSource = (HikariDataSource) applicationContext.getBean(DataSource, Qualifiers.byName("foo")).targetDataSource + dataSource = (HikariDataSource) dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("foo"))) then: dataSource.jdbcUrl == 'jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -260,13 +266,14 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default.data-source-properties' : ['reWriteBatchInserts' : true, 'anotherOne' : 'value']] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - HikariDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: !dataSource.dataSourceProperties.isEmpty() @@ -286,9 +293,10 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default.automatic-validation-query': false] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) when: - HikariUrlDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + HikariUrlDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.jdbcUrl == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' diff --git a/jdbc-tomcat/build.gradle b/jdbc-tomcat/build.gradle index a2ffc39c8..27f4aa594 100644 --- a/jdbc-tomcat/build.gradle +++ b/jdbc-tomcat/build.gradle @@ -10,13 +10,10 @@ dependencies { testRuntimeOnly(libs.managed.h2) testAnnotationProcessor(mn.micronaut.inject.java) - testImplementation(mnSpring.micronaut.spring) testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mn.micronaut.management) testImplementation(mnMicrometer.micronaut.micrometer.core) testImplementation(mnCache.micronaut.cache.core) - - testImplementation(mnSpring.spring.jdbc) } diff --git a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/BookService.java b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/BookService.java index 5712a3cb1..157ffeab8 100644 --- a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/BookService.java +++ b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/BookService.java @@ -17,7 +17,6 @@ import jakarta.inject.Named; import jakarta.inject.Singleton; -import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.sql.Connection; @@ -48,27 +47,32 @@ public BookService(DataSource dataSource, @Named("secondary") DataSource seconda } } - @Transactional public String save(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } - @Transactional public String longsave(String title) throws SQLException { try (Connection connection = dataSource.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); Thread.sleep(10); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + + connection.commit(); + return Integer.toString(value); } catch (InterruptedException e) { e.printStackTrace(); @@ -77,16 +81,18 @@ public String longsave(String title) throws SQLException { } - @Transactional("secondary") public String saveTwo(String title) throws SQLException { try (Connection connection = secondary.getConnection()) { + connection.setAutoCommit(false); connection.createStatement().execute("UPDATE foo SET id = id + 1;"); ResultSet resultSet = connection.createStatement().executeQuery("SELECT id FROM foo"); resultSet.next(); int value = resultSet.getInt("id"); + connection.commit(); + return Integer.toString(value); } } -} \ No newline at end of file +} diff --git a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceConfigurationSpec.groovy b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceConfigurationSpec.groovy index ef92022ed..d206ae361 100644 --- a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceConfigurationSpec.groovy +++ b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceConfigurationSpec.groovy @@ -21,6 +21,7 @@ import io.micronaut.context.DefaultApplicationContext import io.micronaut.context.env.MapPropertySource import io.micronaut.context.exceptions.NoSuchBeanException import io.micronaut.inject.qualifiers.Qualifiers +import io.micronaut.jdbc.DataSourceResolver import spock.lang.Ignore import spock.lang.Specification @@ -51,6 +52,7 @@ class DatasourceConfigurationSpec extends Specification { ['datasources.default': [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) @@ -58,7 +60,7 @@ class DatasourceConfigurationSpec extends Specification { applicationContext.containsBean(TomcatDataSourcePoolMetadata) when: - DataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + DataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.url == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -117,6 +119,7 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.default.defaultCatalog' : 'catalog'] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) @@ -124,7 +127,7 @@ class DatasourceConfigurationSpec extends Specification { applicationContext.containsBean(TomcatDataSourcePoolMetadata) when: - DataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + DataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: dataSource.abandonWhenPercentageFull == 99 @@ -152,13 +155,14 @@ class DatasourceConfigurationSpec extends Specification { 'datasources.foo' : [:]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - DataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + DataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.url == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -168,7 +172,7 @@ class DatasourceConfigurationSpec extends Specification { dataSource.driverClassName == 'org.h2.Driver' when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("foo")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("foo"))) then: //The default configuration is supplied because H2 is on the classpath dataSource.url == 'jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -212,6 +216,7 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.getBeansOfType(DataSource).size() == 2 @@ -224,7 +229,7 @@ class DatasourceConfigurationSpec extends Specification { thrown(NoSuchBeanException) when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("default")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("default"))) then: dataSource.abandonWhenPercentageFull == 99 @@ -238,7 +243,7 @@ class DatasourceConfigurationSpec extends Specification { dataSource.defaultCatalog == 'catalog' when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource.abandonWhenPercentageFull == 99 @@ -334,9 +339,10 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) when: - org.apache.tomcat.jdbc.pool.DataSource dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + org.apache.tomcat.jdbc.pool.DataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource.getPool() @@ -371,9 +377,10 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) when: - org.apache.tomcat.jdbc.pool.DataSource dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + org.apache.tomcat.jdbc.pool.DataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource.getPool() diff --git a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceFactorySpec.groovy b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceFactorySpec.groovy index d11d0d7f5..7a6c7ccdd 100644 --- a/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceFactorySpec.groovy +++ b/jdbc-tomcat/src/test/groovy/io/micronaut/configuration/jdbc/tomcat/DatasourceFactorySpec.groovy @@ -15,22 +15,23 @@ */ package io.micronaut.configuration.jdbc.tomcat -import io.micronaut.jdbc.spring.SpringDataSourceResolver +import io.micronaut.jdbc.DataSourceResolver import org.apache.tomcat.jdbc.pool.DataSource -import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy import spock.lang.Specification class DatasourceFactorySpec extends Specification { DatasourceFactory datasourceFactory - def setup() { - datasourceFactory = new DatasourceFactory(new SpringDataSourceResolver()) - } - def "create basic datasource"() { given: def dataSource = new DataSource(validationQuery: "SELECT 1") + DatasourceFactory datasourceFactory = new DatasourceFactory(new DataSourceResolver() { + @Override + javax.sql.DataSource resolve(javax.sql.DataSource ds) { + return ds + } + }) when: def metadata = datasourceFactory.tomcatPoolDataSourceMetadataProvider(dataSource) @@ -47,10 +48,19 @@ class DatasourceFactorySpec extends Specification { def "create transactional datasource"() { given: def dataSource = new DataSource(validationQuery: "SELECT 1") - def transactionalDataSource = new TransactionAwareDataSourceProxy(targetDataSource: dataSource) + def proxyDataSource = Spy(dataSource) + def dataSourceResolver = new DataSourceResolver() { + @Override + javax.sql.DataSource resolve(javax.sql.DataSource ds) { + if (ds.is(proxyDataSource)) { + return dataSource + } + return ds + } + } when: - def metadata = datasourceFactory.tomcatPoolDataSourceMetadataProvider(transactionalDataSource) + def metadata = new DatasourceFactory(dataSourceResolver).tomcatPoolDataSourceMetadataProvider(proxyDataSource) then: metadata diff --git a/jdbc-ucp/build.gradle b/jdbc-ucp/build.gradle index dbd7ae4ec..c41cec7aa 100644 --- a/jdbc-ucp/build.gradle +++ b/jdbc-ucp/build.gradle @@ -12,7 +12,6 @@ dependencies { testRuntimeOnly(libs.managed.h2) testAnnotationProcessor(mn.micronaut.inject.java) - testImplementation(mnSpring.micronaut.spring) testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mn.micronaut.management) diff --git a/jdbc-ucp/src/test/groovy/io/micronaut/configuration/jdbc/ucp/DatasourceConfigurationSpec.groovy b/jdbc-ucp/src/test/groovy/io/micronaut/configuration/jdbc/ucp/DatasourceConfigurationSpec.groovy index 591d3b9ab..efd513354 100644 --- a/jdbc-ucp/src/test/groovy/io/micronaut/configuration/jdbc/ucp/DatasourceConfigurationSpec.groovy +++ b/jdbc-ucp/src/test/groovy/io/micronaut/configuration/jdbc/ucp/DatasourceConfigurationSpec.groovy @@ -19,6 +19,7 @@ import io.micronaut.context.ApplicationContext import io.micronaut.context.DefaultApplicationContext import io.micronaut.context.env.MapPropertySource import io.micronaut.inject.qualifiers.Qualifiers +import io.micronaut.jdbc.DataSourceResolver import oracle.ucp.jdbc.PoolDataSource import spock.lang.Specification @@ -54,13 +55,14 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(PoolDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.getURL() == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -82,13 +84,14 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(PoolDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.getURL() == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -115,13 +118,14 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(PoolDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: dataSource.getInitialPoolSize() == 5 @@ -152,20 +156,21 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(DataSource) applicationContext.containsBean(DatasourceConfiguration) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.getURL() == 'jdbc:h2:mem:default;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' dataSource.getUser() == 'sa' when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("foo")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("foo"))) then: //The default configuration is supplied because H2 is on the classpath dataSource.getURL() == 'jdbc:h2:mem:foo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE' @@ -202,13 +207,14 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.getBeansOfType(DataSource).size() == 2 applicationContext.getBeansOfType(DatasourceConfiguration).size() == 2 when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("default")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("default"))) then: dataSource.getInitialPoolSize() == 5 @@ -220,7 +226,7 @@ class DatasourceConfigurationSpec extends Specification { dataSource.getLoginTimeout() == 20 when: - dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource.getInitialPoolSize() == 5 @@ -260,9 +266,10 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource @@ -296,9 +303,10 @@ class DatasourceConfigurationSpec extends Specification { ] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource, Qualifiers.byName("person")).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource, Qualifiers.byName("person"))) then: dataSource @@ -316,13 +324,14 @@ class DatasourceConfigurationSpec extends Specification { ["datasources.default.data-source-properties": ["oracle.fan.enabled": true]] )) applicationContext.start() + DataSourceResolver dataSourceResolver = applicationContext.findBean(DataSourceResolver).orElse(DataSourceResolver.DEFAULT) expect: applicationContext.containsBean(PoolDataSource) applicationContext.containsBean(DatasourceConfiguration) when: - PoolDataSource dataSource = applicationContext.getBean(DataSource).targetDataSource + PoolDataSource dataSource = dataSourceResolver.resolve(applicationContext.getBean(DataSource)) then: //The default configuration is supplied because H2 is on the classpath dataSource.getSQLForValidateConnection()== 'SELECT 1' diff --git a/jdbc/build.gradle b/jdbc/build.gradle index 5e5e4d6a7..212f1e0a6 100644 --- a/jdbc/build.gradle +++ b/jdbc/build.gradle @@ -6,9 +6,4 @@ dependencies { annotationProcessor(mn.micronaut.graal) api(mn.micronaut.inject) - - compileOnly(mnSpring.micronaut.spring) - - compileOnly(mnSpring.spring.jdbc) - compileOnly(mnSpring.spring.tx) } diff --git a/jdbc/src/main/java/io/micronaut/jdbc/spring/HibernatePresenceCondition.java b/jdbc/src/main/java/io/micronaut/jdbc/spring/HibernatePresenceCondition.java deleted file mode 100644 index eefc32661..000000000 --- a/jdbc/src/main/java/io/micronaut/jdbc/spring/HibernatePresenceCondition.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.jdbc.spring; - -import io.micronaut.context.BeanContext; -import io.micronaut.context.condition.Condition; -import io.micronaut.context.condition.ConditionContext; -import io.micronaut.core.annotation.Internal; -import io.micronaut.core.reflect.ClassUtils; - -/** - * Disables the datasource configuration if Hibernate is present. - * - * @author graemerocher - * @since 1.0 - */ -@Internal -public final class HibernatePresenceCondition implements Condition { - @Override - public boolean matches(ConditionContext context) { - BeanContext beanContext = context.getBeanContext(); - return !ClassUtils.isPresent("io.micronaut.configuration.hibernate.jpa.HibernateTransactionManagerFactory", beanContext.getClassLoader()); - } -} diff --git a/jdbc/src/main/java/io/micronaut/jdbc/spring/SpringDataSourceResolver.java b/jdbc/src/main/java/io/micronaut/jdbc/spring/SpringDataSourceResolver.java deleted file mode 100644 index 7e296c6e8..000000000 --- a/jdbc/src/main/java/io/micronaut/jdbc/spring/SpringDataSourceResolver.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.jdbc.spring; - -import io.micronaut.context.annotation.Requires; -import io.micronaut.core.annotation.Internal; -import io.micronaut.jdbc.DataSourceResolver; -import jakarta.inject.Singleton; -import org.springframework.jdbc.datasource.DelegatingDataSource; - -import javax.sql.DataSource; - -/** - * Unwraps spring data source proxies. - * - * @author graemerocher - * @since 1.0 - */ -@Singleton -@Internal -@Requires(classes = DelegatingDataSource.class) -public final class SpringDataSourceResolver implements DataSourceResolver { - - @Override - public DataSource resolve(DataSource dataSource) { - while (dataSource instanceof DelegatingDataSource) { - dataSource = ((DelegatingDataSource) dataSource).getTargetDataSource(); - } - return dataSource; - } -} diff --git a/jdbc/src/main/java/io/micronaut/jdbc/spring/package-info.java b/jdbc/src/main/java/io/micronaut/jdbc/spring/package-info.java deleted file mode 100644 index dcefd7740..000000000 --- a/jdbc/src/main/java/io/micronaut/jdbc/spring/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Classes for configuring transaction management via Spring for data sources. - * - * @author graemerocher - * @since 1.0 - */ -package io.micronaut.jdbc.spring; diff --git a/jdbi/build.gradle b/jdbi/build.gradle index 34006fb0f..2d72c02b8 100644 --- a/jdbi/build.gradle +++ b/jdbi/build.gradle @@ -28,7 +28,6 @@ dependencies { testRuntimeOnly projects.micronautJdbcHikari testRuntimeOnly(libs.managed.h2) - testRuntimeOnly(mnSpring.spring.jdbc) testAnnotationProcessor(mn.micronaut.inject.java) testAnnotationProcessor(mnSpring.micronaut.spring.annotation) @@ -36,6 +35,7 @@ dependencies { testImplementation(mn.micronaut.http.server.netty) testImplementation(mn.micronaut.http.client) testImplementation(mn.micronaut.management) + testImplementation(mnSpring.spring.jdbc) testImplementation(mnMicrometer.micronaut.micrometer.core) diff --git a/jdbc/src/main/java/io/micronaut/jdbc/spring/DataSourceTransactionManagerFactory.java b/jdbi/src/test/groovy/io/micronaut/configuration/jdbi/DataSourceTransactionManagerFactory.java similarity index 97% rename from jdbc/src/main/java/io/micronaut/jdbc/spring/DataSourceTransactionManagerFactory.java rename to jdbi/src/test/groovy/io/micronaut/configuration/jdbi/DataSourceTransactionManagerFactory.java index 59f8cce93..13491e544 100644 --- a/jdbc/src/main/java/io/micronaut/jdbc/spring/DataSourceTransactionManagerFactory.java +++ b/jdbi/src/test/groovy/io/micronaut/configuration/jdbi/DataSourceTransactionManagerFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.micronaut.jdbc.spring; +package io.micronaut.configuration.jdbi; import io.micronaut.context.annotation.EachBean; import io.micronaut.context.annotation.Factory; @@ -36,7 +36,6 @@ */ @Factory @Requires(classes = DataSourceTransactionManager.class) -@Requires(condition = HibernatePresenceCondition.class) @Internal public class DataSourceTransactionManagerFactory { diff --git a/jooq/src/test/groovy/io/micronaut/configuration/jooq/spring/DataSourceTransactionManagerFactory.java b/jooq/src/test/groovy/io/micronaut/configuration/jooq/spring/DataSourceTransactionManagerFactory.java new file mode 100644 index 000000000..accb791ca --- /dev/null +++ b/jooq/src/test/groovy/io/micronaut/configuration/jooq/spring/DataSourceTransactionManagerFactory.java @@ -0,0 +1,90 @@ +/* + * Copyright 2017-2020 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.configuration.jooq.spring; + +import io.micronaut.context.annotation.EachBean; +import io.micronaut.context.annotation.Factory; +import io.micronaut.context.annotation.Requires; +import io.micronaut.context.event.BeanCreatedEvent; +import io.micronaut.context.event.BeanCreatedEventListener; +import io.micronaut.context.event.BeanPreDestroyEventListener; +import io.micronaut.core.annotation.Internal; +import jakarta.inject.Singleton; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; + +import javax.sql.DataSource; + +/** + * Configures a {@link DataSourceTransactionManager} for each configured JDBC {@link DataSource}. + * + * @author graemerocher + * @since 1.0 + */ +@Factory +@Requires(classes = DataSourceTransactionManager.class) +@Internal +public class DataSourceTransactionManagerFactory { + + /** + * For each {@link DataSource} add a {@link DataSourceTransactionManager} bean. + * + * @param dataSource The data source + * @return The bean to add + */ + @EachBean(DataSource.class) + DataSourceTransactionManager dataSourceTransactionManager( + DataSource dataSource) { + DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); + dataSourceTransactionManager.afterPropertiesSet(); + return dataSourceTransactionManager; + } + + /** + * For each data source, wrap in a {@link TransactionAwareDataSourceProxy}. + * @return The listener that will wrap each data source + */ + @Singleton + TransactionAwareDataSourceListener transactionAwareDataSourceListener() { + return new TransactionAwareDataSourceListener(); + } + + @Singleton + final BeanPreDestroyEventListener transactionAwareDataSourceListenerUnwrapper() { + return event -> { + DataSource ds = event.getBean(); + if (ds instanceof TransactionAwareDataSourceProxy) { + return ((TransactionAwareDataSourceProxy) ds).getTargetDataSource(); + } + return ds; + }; + } + + /** + * A {@link BeanCreatedEventListener} that wraps each data source in a transaction aware proxy. + */ + private static class TransactionAwareDataSourceListener implements BeanCreatedEventListener { + @Override + public DataSource onCreated(BeanCreatedEvent event) { + DataSource dataSource = event.getBean(); + if (dataSource instanceof TransactionAwareDataSourceProxy) { + return dataSource; + } else { + return new TransactionAwareDataSourceProxy(dataSource); + } + } + } +} diff --git a/settings.gradle b/settings.gradle index cceacc733..4de0d9f91 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,7 +35,6 @@ include 'jdbc-tomcat' include 'jdbc-ucp' include 'jasync-sql' include 'hibernate-jpa' -include 'hibernate-jpa-spring' include 'hibernate-reactive' include 'jooq' diff --git a/sql-bom/build.gradle b/sql-bom/build.gradle index d091cc316..00286e6db 100644 --- a/sql-bom/build.gradle +++ b/sql-bom/build.gradle @@ -10,10 +10,11 @@ micronautBom { micronautBom { suppressions { + acceptedLibraryRegressions.add("micronaut-hibernate-jpa-spring") acceptedLibraryRegressions.add("commons-dbcp-compat") acceptedVersionRegressions.add("commons-dbcp-compat") acceptedLibraryRegressions.add("commons-dbcp") - dependencies.addAll([ + dependencies.addAll([ "org.jdbi:jdbi3-core:3.38.3", "org.jdbi:jdbi3-sqlobject:3.38.3", "org.jdbi:jdbi3-json:3.38.3" diff --git a/src/main/docs/guide/hibernate/hibernate-spring-transaction.adoc b/src/main/docs/guide/hibernate/hibernate-spring-transaction.adoc deleted file mode 100644 index f081bdabb..000000000 --- a/src/main/docs/guide/hibernate/hibernate-spring-transaction.adoc +++ /dev/null @@ -1,7 +0,0 @@ -Since 2.0, by default Micronaut-based transaction management is enabled. Thus on any service you can use the `io.micronaut.transaction.annotation.TransactionalAdvice` annotation (or the `javax.transaction.Transactional` annotation if you include the `micronaut-data-processor` dependency in your annotation processor configuration). - -If you wish to use Spring-based transaction management instead you should add the following dependency: - -dependency:micronaut-hibernate-jpa-spring[groupId="io.micronaut.sql"] - -Which will enable configuration of the Spring transaction management instead. diff --git a/src/main/docs/guide/jdbc/jdbc-spring-transaction.adoc b/src/main/docs/guide/jdbc/jdbc-spring-transaction.adoc deleted file mode 100644 index a7bf11894..000000000 --- a/src/main/docs/guide/jdbc/jdbc-spring-transaction.adoc +++ /dev/null @@ -1,9 +0,0 @@ -If you wish to use Spring-based transaction management you can add the following dependencies to your application: - -dependency:micronaut-spring[groupId="io.micronaut.spring", scope="compile"] - -dependency:spring-jdbc[groupId="org.springframework", scope="runtime"] - -Micronaut will automatically configure a `DataSourceTransactionManager` and wrap the `DataSource` in a `TransactionAwareDataSourceProxy` for each configured `DataSource`. - -For transactions to work, use spring's https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html[@Transactional] annotation and https://micronaut-projects.github.io/micronaut-spring/latest/guide/#springToMicronautStart[configure micronaut-spring-annotation in your annotation processor path]. diff --git a/src/main/docs/guide/toc.yml b/src/main/docs/guide/toc.yml index 33b61e112..8acfa9baa 100644 --- a/src/main/docs/guide/toc.yml +++ b/src/main/docs/guide/toc.yml @@ -5,7 +5,6 @@ jdbc: jdbc-connection-pools: Configuring JDBC Connection Pools jdbc-multiple-datasources: Configuring Multiple Data Sources jdbc-healthchecks: JDBC Health Checks - jdbc-spring-transaction: Using Spring Transaction Management hibernate: title: Configuring Hibernate hibernate-inject-session: Injecting an EntityManager or Hibernate Session @@ -13,7 +12,6 @@ hibernate: hibernate-entity-scan: Entity Scan Configuration hibernate-reactive: Configuring Hibernate Reactive hibernate-proxies: Using compile-time Hibernate proxies - hibernate-spring-transaction: Using Spring Transaction Management hibernate-lazy-initialization: Understanding LazyInitializationException jasync: title: Configuring JAsync SQL