Skip to content

Commit

Permalink
Replace BatchJdbcOperations with Spring's `NamedParameterJdbcOperat…
Browse files Browse the repository at this point in the history
…ions`.

BatchJdbcOperations is still there, but deprecated, and not used except for deprecated places kept for backward compatibility.

This is possible since Spring Framework made the features offered by `BatchJdbcOperations` part of `NamedParameterJdbcOperations`.

Closes #1616
  • Loading branch information
schauder authored and mp911de committed Oct 11, 2023
1 parent 6887ca7 commit 5d6d575
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
*
* @author Chirag Tailor
* @since 2.4
* @deprecated Use the standard {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations} instead.
*/
@Deprecated(since = "3.2")
public class BatchJdbcOperations {

private final JdbcOperations jdbcOperations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.IdGeneration;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.lang.Nullable;
Expand All @@ -33,21 +34,23 @@
*
* @author Chirag Tailor
* @author Kurt Niemi
* @author Jens Schauder
* @since 2.4
*/
class IdGeneratingBatchInsertStrategy implements BatchInsertStrategy {

private final InsertStrategy insertStrategy;
private final Dialect dialect;
private final BatchJdbcOperations batchJdbcOperations;
private final NamedParameterJdbcOperations jdbcOperations;
private final SqlIdentifier idColumn;

IdGeneratingBatchInsertStrategy(InsertStrategy insertStrategy, Dialect dialect,
BatchJdbcOperations batchJdbcOperations, @Nullable SqlIdentifier idColumn) {
NamedParameterJdbcOperations jdbcOperations, @Nullable SqlIdentifier idColumn) {

this.insertStrategy = insertStrategy;
this.dialect = dialect;
this.batchJdbcOperations = batchJdbcOperations;
this.jdbcOperations = jdbcOperations;

this.idColumn = idColumn;
}

Expand All @@ -66,12 +69,12 @@ public Object[] execute(String sql, SqlParameterSource[] sqlParameterSources) {

String[] keyColumnNames = getKeyColumnNames();
if (keyColumnNames.length == 0) {
batchJdbcOperations.batchUpdate(sql, sqlParameterSources, holder);
jdbcOperations.batchUpdate(sql, sqlParameterSources, holder);
} else {
batchJdbcOperations.batchUpdate(sql, sqlParameterSources, holder, keyColumnNames);
jdbcOperations.batchUpdate(sql, sqlParameterSources, holder, keyColumnNames);
}
} else {
batchJdbcOperations.batchUpdate(sql, sqlParameterSources, holder);
jdbcOperations.batchUpdate(sql, sqlParameterSources, holder);
}
Object[] ids = new Object[sqlParameterSources.length];
List<Map<String, Object>> keyList = holder.getKeyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,32 @@
* whether the insert is expected to generate ids.
*
* @author Chirag Tailor
* @author Jens Schauder
* @since 2.4
*/
public class InsertStrategyFactory {

private final NamedParameterJdbcOperations namedParameterJdbcOperations;
private final BatchJdbcOperations batchJdbcOperations;
private final NamedParameterJdbcOperations jdbcOperations;
private final Dialect dialect;

public InsertStrategyFactory(NamedParameterJdbcOperations namedParameterJdbcOperations,
BatchJdbcOperations batchJdbcOperations, Dialect dialect) {
public InsertStrategyFactory(NamedParameterJdbcOperations jdbcOperations, Dialect dialect) {

this.namedParameterJdbcOperations = namedParameterJdbcOperations;
this.batchJdbcOperations = batchJdbcOperations;
this.jdbcOperations = jdbcOperations;
this.dialect = dialect;
}

/**
* Constructor with additional {@link BatchJdbcOperations} constructor.
*
* @deprecated Use the {@link InsertStrategyFactory#InsertStrategyFactory(NamedParameterJdbcOperations, Dialect)}
* instead.
*/
@Deprecated(since = "3.2")
public InsertStrategyFactory(NamedParameterJdbcOperations namedParameterJdbcOperations,
BatchJdbcOperations batchJdbcOperations, Dialect dialect) {
this(namedParameterJdbcOperations, dialect);
}

/**
* @param idValueSource the {@link IdValueSource} for the insert.
* @param idColumn the identifier for the id, if an id is expected to be generated. May be {@code null}.
Expand All @@ -52,9 +62,9 @@ public InsertStrategyFactory(NamedParameterJdbcOperations namedParameterJdbcOper
InsertStrategy insertStrategy(IdValueSource idValueSource, @Nullable SqlIdentifier idColumn) {

if (IdValueSource.GENERATED.equals(idValueSource)) {
return new IdGeneratingInsertStrategy(dialect, namedParameterJdbcOperations, idColumn);
return new IdGeneratingInsertStrategy(dialect, jdbcOperations, idColumn);
}
return new DefaultInsertStrategy(namedParameterJdbcOperations);
return new DefaultInsertStrategy(jdbcOperations);
}

/**
Expand All @@ -66,11 +76,10 @@ InsertStrategy insertStrategy(IdValueSource idValueSource, @Nullable SqlIdentifi
BatchInsertStrategy batchInsertStrategy(IdValueSource idValueSource, @Nullable SqlIdentifier idColumn) {

if (IdValueSource.GENERATED.equals(idValueSource)) {
return new IdGeneratingBatchInsertStrategy(
new IdGeneratingInsertStrategy(dialect, namedParameterJdbcOperations, idColumn), dialect, batchJdbcOperations,
idColumn);
return new IdGeneratingBatchInsertStrategy(new IdGeneratingInsertStrategy(dialect, jdbcOperations, idColumn),
dialect, jdbcOperations, idColumn);
}
return new DefaultBatchInsertStrategy(namedParameterJdbcOperations);
return new DefaultBatchInsertStrategy(jdbcOperations);
}

private static class DefaultInsertStrategy implements InsertStrategy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingC

SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, converter, dialect);
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations,
new BatchJdbcOperations(operations.getJdbcOperations()), dialect);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations, dialect);

DataAccessStrategy defaultDataAccessStrategy = new DataAccessStrategyFactory( //
sqlGeneratorSource, //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations op
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect);
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations,
new SqlParametersFactory(context, jdbcConverter),
new InsertStrategyFactory(operations, new BatchJdbcOperations(operations.getJdbcOperations()), dialect));
new InsertStrategyFactory(operations, dialect));

return factory.create();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.jdbc.core.convert.BatchJdbcOperations;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.DataAccessStrategyFactory;
import org.springframework.data.jdbc.core.convert.InsertStrategyFactory;
Expand Down Expand Up @@ -179,8 +178,7 @@ public void afterPropertiesSet() {
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(this.mappingContext, this.converter,
this.dialect);
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(this.mappingContext, this.converter);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations,
new BatchJdbcOperations(this.operations.getJdbcOperations()), this.dialect);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations, this.dialect);

DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, this.converter,
this.operations, sqlParametersFactory, insertStrategyFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.data.relational.core.dialect.LockClause;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.KeyHolder;

Expand All @@ -41,7 +42,7 @@ class IdGeneratingBatchInsertStrategyTest {

SqlIdentifier idColumn = SqlIdentifier.quoted("id");
IdentifierProcessing identifierProcessing = IdentifierProcessing.ANSI;
BatchJdbcOperations batchJdbcOperations = mock(BatchJdbcOperations.class);
NamedParameterJdbcOperations jdbcOperations = mock(NamedParameterJdbcOperations.class);
InsertStrategy insertStrategy = mock(InsertStrategy.class);
String sql = "some sql";
SqlParameterSource[] sqlParameterSources = new SqlParameterSource[] { new SqlIdentifierParameterSource() };
Expand All @@ -50,7 +51,7 @@ class IdGeneratingBatchInsertStrategyTest {
void insertsSequentially_whenIdGenerationForBatchOperationsNotSupported() {

BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, true, false), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, true, false), jdbcOperations, idColumn);

SqlIdentifierParameterSource sqlParameterSource1 = new SqlIdentifierParameterSource();
sqlParameterSource1.addValue(SqlIdentifier.quoted("property1"), "value1");
Expand All @@ -72,41 +73,41 @@ void insertsSequentially_whenIdGenerationForBatchOperationsNotSupported() {
void insertsWithKeyHolderAndKeyColumnNames_whenDriverRequiresKeyColumnNames() {

BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, true, true), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, true, true), jdbcOperations, idColumn);

batchInsertStrategy.execute(sql, sqlParameterSources);

verify(batchJdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class),
verify(jdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class),
eq(new String[] { idColumn.getReference() }));
}

@Test
void insertsWithKeyHolder_whenDriverRequiresKeyColumnNames_butIdColumnIsNull() {

BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, true, true), batchJdbcOperations, null);
createDialect(identifierProcessing, true, true), jdbcOperations, null);

batchInsertStrategy.execute(sql, sqlParameterSources);

verify(batchJdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class));
verify(jdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class));
}

@Test
void insertsWithKeyHolder_whenDriverDoesNotRequireKeyColumnNames() {

BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, false, true), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, false, true), jdbcOperations, idColumn);

batchInsertStrategy.execute(sql, sqlParameterSources);

verify(batchJdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class));
verify(jdbcOperations).batchUpdate(eq(sql), eq(sqlParameterSources), any(KeyHolder.class));
}

@Test
void insertsWithKeyHolder_returningKey_whenThereIsOnlyOne() {

Long idValue = 123L;
when(batchJdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {
when(jdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {

KeyHolder keyHolder = invocationOnMock.getArgument(2);
HashMap<String, Object> keys = new HashMap<>();
Expand All @@ -115,7 +116,7 @@ void insertsWithKeyHolder_returningKey_whenThereIsOnlyOne() {
return null;
});
BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, false, true), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, false, true), jdbcOperations, idColumn);

Object[] ids = batchInsertStrategy.execute(sql, sqlParameterSources);

Expand All @@ -126,7 +127,7 @@ void insertsWithKeyHolder_returningKey_whenThereIsOnlyOne() {
void insertsWithKeyHolder_returningKeyMatchingIdColumn_whenKeyHolderContainsMultipleKeysPerRecord() {

Long idValue = 123L;
when(batchJdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {
when(jdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {

KeyHolder keyHolder = invocationOnMock.getArgument(2);
HashMap<String, Object> keys = new HashMap<>();
Expand All @@ -136,7 +137,7 @@ void insertsWithKeyHolder_returningKeyMatchingIdColumn_whenKeyHolderContainsMult
return null;
});
BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, false, true), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, false, true), jdbcOperations, idColumn);

Object[] ids = batchInsertStrategy.execute(sql, sqlParameterSources);

Expand All @@ -147,7 +148,7 @@ void insertsWithKeyHolder_returningKeyMatchingIdColumn_whenKeyHolderContainsMult
void insertsWithKeyHolder_returningNull__whenKeyHolderContainsMultipleKeysPerRecord_butIdColumnIsNull() {

Long idValue = 123L;
when(batchJdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {
when(jdbcOperations.batchUpdate(any(), any(), any())).thenAnswer(invocationOnMock -> {

KeyHolder keyHolder = invocationOnMock.getArgument(2);
HashMap<String, Object> keys = new HashMap<>();
Expand All @@ -157,7 +158,7 @@ void insertsWithKeyHolder_returningNull__whenKeyHolderContainsMultipleKeysPerRec
return null;
});
BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, false, true), batchJdbcOperations, null);
createDialect(identifierProcessing, false, true), jdbcOperations, null);

Object[] ids = batchInsertStrategy.execute(sql, sqlParameterSources);

Expand All @@ -169,7 +170,7 @@ void insertsWithKeyHolder_returningNull__whenKeyHolderContainsMultipleKeysPerRec
void insertsWithKeyHolder_returningNull_whenKeyHolderHasNoKeys() {

BatchInsertStrategy batchInsertStrategy = new IdGeneratingBatchInsertStrategy(insertStrategy,
createDialect(identifierProcessing, false, true), batchJdbcOperations, idColumn);
createDialect(identifierProcessing, false, true), jdbcOperations, idColumn);

Object[] ids = batchInsertStrategy.execute(sql, sqlParameterSources);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@
class InsertStrategyFactoryTest {

NamedParameterJdbcOperations namedParameterJdbcOperations = mock(NamedParameterJdbcOperations.class);
BatchJdbcOperations batchJdbcOperations = mock(BatchJdbcOperations.class);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(namedParameterJdbcOperations,
batchJdbcOperations, AnsiDialect.INSTANCE);
AnsiDialect.INSTANCE);

String sql = "some sql";
SqlParameterSource sqlParameterSource = new SqlIdentifierParameterSource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
*/
package org.springframework.data.jdbc.repository;

import static java.util.Arrays.*;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.stubbing.Answer;
Expand All @@ -23,7 +33,15 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.core.convert.BasicJdbcConverter;
import org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy;
import org.springframework.data.jdbc.core.convert.DefaultJdbcTypeFactory;
import org.springframework.data.jdbc.core.convert.DelegatingDataAccessStrategy;
import org.springframework.data.jdbc.core.convert.InsertStrategyFactory;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
import org.springframework.data.jdbc.core.convert.SqlParametersFactory;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.repository.support.SimpleJdbcRepository;
Expand All @@ -48,16 +66,6 @@
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.lang.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static java.util.Arrays.*;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

/**
* Unit tests for application events via {@link SimpleJdbcRepository}.
*
Expand Down Expand Up @@ -90,8 +98,7 @@ void before() {
new DefaultJdbcTypeFactory(operations.getJdbcOperations()), dialect.getIdentifierProcessing());
SqlGeneratorSource generatorSource = new SqlGeneratorSource(context, converter, dialect);
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations,
new BatchJdbcOperations(operations.getJdbcOperations()), dialect);
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(operations, dialect);

this.dataAccessStrategy = spy(new DefaultDataAccessStrategy(generatorSource, context, converter, operations,
sqlParametersFactory, insertStrategyFactory));
Expand Down Expand Up @@ -299,8 +306,7 @@ interface DummyEntityRepository
extends CrudRepository<DummyEntity, Long>, PagingAndSortingRepository<DummyEntity, Long> {}

static final class DummyEntity {
@Id
private final Long id;
@Id private final Long id;

public DummyEntity(Long id) {
this.id = id;
Expand All @@ -311,12 +317,15 @@ public Long getId() {
}

public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof DummyEntity)) return false;
if (o == this)
return true;
if (!(o instanceof DummyEntity))
return false;
final DummyEntity other = (DummyEntity) o;
final Object this$id = this.getId();
final Object other$id = other.getId();
if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false;
if (this$id == null ? other$id != null : !this$id.equals(other$id))
return false;
return true;
}

Expand Down
Loading

0 comments on commit 5d6d575

Please sign in to comment.