Skip to content

Commit

Permalink
Fix Spring tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dstepanov committed Jun 5, 2023
1 parent 1f310bf commit 352d039
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package io.micronaut.data.hibernate.connection;

import io.micronaut.context.annotation.EachBean;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.Nullable;
Expand All @@ -32,7 +31,6 @@
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.SessionImplementor;

import javax.sql.DataSource;
import java.sql.Connection;

/**
Expand All @@ -43,15 +41,15 @@
*/
@Internal
@RequiresSyncHibernate
@EachBean(DataSource.class)
@EachBean(SessionFactory.class)
@Replaces(DataSourceConnectionOperations.class)
public final class HibernateConnectionOperations extends AbstractConnectionOperations<Session> implements ContextualConnectionProvider {

private final SessionFactory sessionFactory;
@Nullable
private final Interceptor entityInterceptor;

public HibernateConnectionOperations(@Parameter SessionFactory sessionFactory,
public HibernateConnectionOperations(SessionFactory sessionFactory,
@Nullable Interceptor entityInterceptor) {
this.sessionFactory = sessionFactory;
this.entityInterceptor = entityInterceptor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2017-2023 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.data.spring.jpa.hibernate;

import io.micronaut.context.annotation.EachBean;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.core.annotation.Internal;
import io.micronaut.data.connection.manager.ConnectionDefinition;
import io.micronaut.data.connection.manager.synchronous.ConnectionOperations;
import io.micronaut.data.connection.manager.synchronous.ConnectionStatus;
import io.micronaut.data.connection.support.DefaultConnectionStatus;
import io.micronaut.data.hibernate.connection.HibernateConnectionOperations;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Optional;
import java.util.function.Function;

/**
* Spring JDBC Hibernate Session operations.
*
* @author Denis Stepanov
* @since 4.0.0
*/
@Internal
@EachBean(SessionFactory.class)
@Replaces(HibernateConnectionOperations.class)
// TODO: We should avoid using @Replaces, there should be a way to use different data sources with Micronaut and Spring TX
public final class SpringHibernateConnectionOperations implements ConnectionOperations<Session> {

private final SessionFactory sessionFactory;

SpringHibernateConnectionOperations(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}

@Override
public Optional<ConnectionStatus<Session>> findConnectionStatus() {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null && sessionHolder.getEntityManager() != null) {
return Optional.of(createStatus(sessionHolder.getSession()));
}
return Optional.empty();
}

@Override
public <R> R execute(ConnectionDefinition definition, Function<ConnectionStatus<Session>, R> callback) {
return new HibernateTemplate(sessionFactory).execute(session -> callback.apply(createStatus(session)));
}

private DefaultConnectionStatus<Session> createStatus(Session session) {
return new DefaultConnectionStatus<>(
session,
ConnectionDefinition.DEFAULT,
true
);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.micronaut.data.spring.hibernate

import io.micronaut.test.support.TestPropertyProvider

trait H2Properties implements TestPropertyProvider {

@Override
Map<String, String> getProperties() {
return [
"datasources.default.name" : "mydb",
"datasources.default.transactionManager" : "springHibernate",
"datasources.default.schema-generate" : "create-drop",
"datasources.default.dialect" : "h2",
"datasources.default.driver-class-name" : "org.h2.Driver",
"datasources.default.username" : "sa",
"datasources.default.password" : "",
"datasources.default.url" : "jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE",
"jpa.default.properties.hibernate.hbm2ddl.auto": "create-drop"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,20 @@
*/
package io.micronaut.data.spring.hibernate

import io.micronaut.context.annotation.Property

import io.micronaut.data.spring.hibernate.spring.SpringCrudRepository
import io.micronaut.data.tck.entities.Person
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Stepwise

import jakarta.inject.Inject

@MicronautTest(rollback = false, packages = "io.micronaut.data.tck.entities")
@Property(name = "datasources.default.name", value = "mydb")
@Property(name = 'jpa.default.properties.hibernate.hbm2ddl.auto', value = 'create-drop')
@Stepwise
class SpringCrudRepositoryJpaSpec extends Specification {
class SpringCrudRepositoryJpaSpec extends Specification implements H2Properties {
@Inject
@Shared
SpringCrudRepository crudRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ class SpringHibernateTransactionSpec extends AbstractTransactionSpec implements
return HibernateBookRepository.class
}

@Override
boolean supportsNoTxProcessing() {
// Spring always tries to flush which fails because there is no transaction
return false
}

@Override
boolean supportsDontRollbackOn() {
return false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
package io.micronaut.data.spring.hibernate

import io.micronaut.context.annotation.Property

import io.micronaut.data.tck.entities.Book
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import io.micronaut.transaction.TransactionOperations
import org.springframework.transaction.annotation.Transactional
import spock.lang.Specification

import jakarta.inject.Inject
import jakarta.persistence.EntityManager

import java.sql.Connection
import org.hibernate.Session
import org.springframework.transaction.annotation.Transactional
import spock.lang.Specification

@MicronautTest(packages = "io.micronaut.data.tck.entities", transactional = false)
@Property(name = "datasources.default.name", value = "mydb")
@Property(name = 'jpa.default.properties.hibernate.hbm2ddl.auto', value = 'create-drop')
class SpringTransactionAnnotation2Spec extends Specification {
class SpringTransactionAnnotation2Spec extends Specification implements H2Properties {

@Inject BookService bookService
@Inject TransactionOperations<Connection> transactionOperations
@Inject TransactionOperations<Session> transactionOperations

void "test transactional annotation"() {
when:
Expand Down Expand Up @@ -55,7 +51,7 @@ class SpringTransactionAnnotation2Spec extends Specification {
@Transactional
static class BookService {
@Inject EntityManager entityManager
@Inject TransactionOperations<java.sql.Connection> transactionOperations
@Inject TransactionOperations<Session> transactionOperations

List<Book> listBooks() {
entityManager.createQuery("from Book").resultList
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
package io.micronaut.data.spring.hibernate

import io.micronaut.context.annotation.Property

import io.micronaut.data.tck.entities.Book
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import io.micronaut.transaction.TransactionOperations
import spock.lang.Specification

import jakarta.inject.Inject
import jakarta.persistence.EntityManager
import jakarta.transaction.Transactional

import java.sql.Connection
import org.hibernate.Session
import spock.lang.Specification

@MicronautTest(packages = "io.micronaut.data.tck.entities", transactional = false)
@Property(name = "datasources.default.name", value = "mydb")
@Property(name = 'jpa.default.properties.hibernate.hbm2ddl.auto', value = 'create-drop')
class SpringTransactionAnnotationSpec extends Specification {
class SpringTransactionAnnotationSpec extends Specification implements H2Properties {

@Inject BookService bookService
@Inject TransactionOperations<Connection> transactionOperations
@Inject TransactionOperations<Session> transactionOperations

void "test transactional annotation"() {
when:
Expand Down Expand Up @@ -55,7 +51,7 @@ class SpringTransactionAnnotationSpec extends Specification {
@Transactional
static class BookService {
@Inject EntityManager entityManager
@Inject TransactionOperations<java.sql.Connection> transactionOperations
@Inject TransactionOperations<Session> transactionOperations

List<Book> listBooks() {
entityManager.createQuery("from Book").resultList
Expand Down
1 change: 1 addition & 0 deletions data-spring/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {

api libs.spring.data.commons

implementation projects.dataConnectionJdbc
implementation projects.dataRuntime
implementation mnSpring.spring.jdbc
implementation mnSpring.micronaut.spring
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
/*
* Copyright 2017-2023 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.data.spring.jdbc;

import io.micronaut.context.annotation.EachBean;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.core.annotation.Internal;
import io.micronaut.data.connection.jdbc.operations.DataSourceConnectionOperationsImpl;
import io.micronaut.data.connection.manager.ConnectionDefinition;
import io.micronaut.data.connection.manager.synchronous.ConnectionOperations;
import io.micronaut.data.connection.manager.synchronous.ConnectionStatus;
Expand All @@ -15,7 +34,17 @@
import java.util.Optional;
import java.util.function.Function;

public class SpringJdbcConnectionOperations implements ConnectionOperations<Connection> {
/**
* Spring JDBC connection operations.
*
* @author Denis Stepanov
* @since 4.0.0
*/
@Internal
@EachBean(DataSource.class)
@Replaces(DataSourceConnectionOperationsImpl.class)
// TODO: We should avoid using @Replaces, there should be a way to use different data sources with Micronaut and Spring TX
public final class SpringJdbcConnectionOperations implements ConnectionOperations<Connection> {

private final DataSource dataSource;

Expand All @@ -29,23 +58,23 @@ public Optional<ConnectionStatus<Connection>> findConnectionStatus() {
if (conHolder != null) {
ConnectionHandle connectionHandle = conHolder.getConnectionHandle();
if (connectionHandle != null) {
return Optional.of(new DefaultConnectionStatus<>(
connectionHandle.getConnection(),
ConnectionDefinition.DEFAULT,
true
));
return Optional.of(createStatus(connectionHandle.getConnection()));
}
}
return Optional.empty();
}

@Override
public <R> R execute(ConnectionDefinition definition, Function<ConnectionStatus<Connection>, R> callback) {
return new JdbcTemplate(dataSource).execute((ConnectionCallback<R>) connection -> callback.apply(new DefaultConnectionStatus<>(
return new JdbcTemplate(dataSource).execute((ConnectionCallback<R>) connection -> callback.apply(createStatus(connection)));
}

private DefaultConnectionStatus<Connection> createStatus(Connection connection) {
return new DefaultConnectionStatus<>(
connection,
ConnectionDefinition.DEFAULT,
true
)));
);
}

}
Loading

0 comments on commit 352d039

Please sign in to comment.