Polishing.

Remove Jetbrains annotation usage.

Simplify code, remove code that is commented out, extract methods, pass PersistentEntity as argument instead of creating instances that hold PersistentEntity as field to align the class lifecycle with its contextual usage.

Refactor AggregateReader lifecycle, use a single instance as there is no entity-specific state attached to AggregateReader.

Add Javadoc.

See #1448
Original pull request: #1622
This commit is contained in:
Mark Paluch
2023-09-27 09:06:59 +02:00
parent 9e795d1349
commit a555119f8b
10 changed files with 255 additions and 280 deletions

View File

@@ -48,30 +48,24 @@ import org.springframework.lang.Nullable;
* intermediate {@link RowDocumentResultSetExtractor RowDocument} and mapped via
* {@link org.springframework.data.relational.core.conversion.RelationalConverter#read(Class, RowDocument)}.
*
* @param <T> the type of aggregate produced by this reader.
* @author Jens Schauder
* @author Mark Paluch
* @since 3.2
*/
class AggregateReader<T> implements PathToColumnMapping {
class AggregateReader implements PathToColumnMapping {
private final RelationalPersistentEntity<T> aggregate;
private final Table table;
private final AliasFactory aliasFactory;
private final SqlGenerator sqlGenerator;
private final JdbcConverter converter;
private final NamedParameterJdbcOperations jdbcTemplate;
private final AliasFactory aliasFactory;
private final RowDocumentResultSetExtractor extractor;
AggregateReader(Dialect dialect, JdbcConverter converter, AliasFactory aliasFactory,
NamedParameterJdbcOperations jdbcTemplate, RelationalPersistentEntity<T> aggregate) {
AggregateReader(Dialect dialect, JdbcConverter converter, NamedParameterJdbcOperations jdbcTemplate) {
this.aliasFactory = new AliasFactory();
this.converter = converter;
this.aggregate = aggregate;
this.jdbcTemplate = jdbcTemplate;
this.table = Table.create(aggregate.getQualifiedTableName());
this.sqlGenerator = new SingleQuerySqlGenerator(converter.getMappingContext(), aliasFactory, dialect, aggregate);
this.aliasFactory = aliasFactory;
this.sqlGenerator = new SingleQuerySqlGenerator(converter.getMappingContext(), aliasFactory, dialect);
this.extractor = new RowDocumentResultSetExtractor(converter.getMappingContext(), this);
}
@@ -92,55 +86,96 @@ class AggregateReader<T> implements PathToColumnMapping {
return aliasFactory.getKeyAlias(path);
}
/**
* Select a single aggregate by its identifier.
*
* @param id the identifier, must not be {@literal null}.
* @param entity the persistent entity type must not be {@literal null}.
* @return the found aggregate root, or {@literal null} if not found.
* @param <T> aggregator type.
*/
@Nullable
public T findById(Object id) {
public <T> T findById(Object id, RelationalPersistentEntity<T> entity) {
Query query = Query.query(Criteria.where(aggregate.getRequiredIdProperty().getName()).is(id)).limit(1);
Query query = Query.query(Criteria.where(entity.getRequiredIdProperty().getName()).is(id)).limit(1);
return findOne(query);
return findOne(query, entity);
}
/**
* Select a single aggregate by a {@link Query}.
*
* @param query the query to run, must not be {@literal null}.
* @param entity the persistent entity type must not be {@literal null}.
* @return the found aggregate root, or {@literal null} if not found.
* @param <T> aggregator type.
*/
@Nullable
public T findOne(Query query) {
return doFind(query, this::extractZeroOrOne);
public <T> T findOne(Query query, RelationalPersistentEntity<T> entity) {
return doFind(query, entity, rs -> extractZeroOrOne(rs, entity));
}
public List<T> findAllById(Iterable<?> ids) {
/**
* Select aggregates by their identifiers.
*
* @param ids the identifiers, must not be {@literal null}.
* @param entity the persistent entity type must not be {@literal null}.
* @return the found aggregate roots. The resulting list can be empty or may not contain objects that correspond to
* the identifiers when the objects are not found in the database.
* @param <T> aggregator type.
*/
public <T> List<T> findAllById(Iterable<?> ids, RelationalPersistentEntity<T> entity) {
Collection<?> identifiers = ids instanceof Collection<?> idl ? idl : Streamable.of(ids).toList();
Query query = Query.query(Criteria.where(aggregate.getRequiredIdProperty().getName()).in(identifiers));
Query query = Query.query(Criteria.where(entity.getRequiredIdProperty().getName()).in(identifiers));
return findAll(query);
return findAll(query, entity);
}
/**
* Select all aggregates by type.
*
* @param entity the persistent entity type must not be {@literal null}.
* @return the found aggregate roots.
* @param <T> aggregator type.
*/
@SuppressWarnings("ConstantConditions")
public <T> List<T> findAll(RelationalPersistentEntity<T> entity) {
return jdbcTemplate.query(sqlGenerator.findAll(entity),
(ResultSetExtractor<? extends List<T>>) rs -> extractAll(rs, entity));
}
/**
* Select all aggregates by query.
*
* @param query the query to run, must not be {@literal null}.
* @param entity the persistent entity type must not be {@literal null}.
* @return the found aggregate roots.
* @param <T> aggregator type.
*/
public <T> List<T> findAll(Query query, RelationalPersistentEntity<T> entity) {
return doFind(query, entity, rs -> extractAll(rs, entity));
}
@SuppressWarnings("ConstantConditions")
public List<T> findAll() {
return jdbcTemplate.query(sqlGenerator.findAll(), this::extractAll);
}
public List<T> findAll(Query query) {
return doFind(query, this::extractAll);
}
@SuppressWarnings("ConstantConditions")
private <R> R doFind(Query query, ResultSetExtractor<R> extractor) {
private <T, R> R doFind(Query query, RelationalPersistentEntity<T> entity, ResultSetExtractor<R> extractor) {
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
Condition condition = createCondition(query, parameterSource);
String sql = sqlGenerator.findAll(condition);
Condition condition = createCondition(query, parameterSource, entity);
String sql = sqlGenerator.findAll(entity, condition);
return jdbcTemplate.query(sql, parameterSource, extractor);
}
@Nullable
private Condition createCondition(Query query, MapSqlParameterSource parameterSource) {
private Condition createCondition(Query query, MapSqlParameterSource parameterSource,
RelationalPersistentEntity<?> entity) {
QueryMapper queryMapper = new QueryMapper(converter);
Optional<CriteriaDefinition> criteria = query.getCriteria();
return criteria
.map(criteriaDefinition -> queryMapper.getMappedObject(parameterSource, criteriaDefinition, table, aggregate))
.orElse(null);
return criteria.map(criteriaDefinition -> queryMapper.getMappedObject(parameterSource, criteriaDefinition,
Table.create(entity.getQualifiedTableName()), entity)).orElse(null);
}
/**
@@ -152,12 +187,13 @@ class AggregateReader<T> implements PathToColumnMapping {
* @return a {@code List} of aggregates, fully converted.
* @throws SQLException on underlying JDBC errors.
*/
private List<T> extractAll(ResultSet rs) throws SQLException {
private <T> List<T> extractAll(ResultSet rs, RelationalPersistentEntity<T> entity) throws SQLException {
Iterator<RowDocument> iterate = extractor.iterate(aggregate, rs);
Iterator<RowDocument> iterate = extractor.iterate(entity, rs);
List<T> resultList = new ArrayList<>();
while (iterate.hasNext()) {
resultList.add(converter.read(aggregate.getType(), iterate.next()));
resultList.add(converter.read(entity.getType(), iterate.next()));
}
return resultList;
@@ -175,17 +211,19 @@ class AggregateReader<T> implements PathToColumnMapping {
* @throws IncorrectResultSizeDataAccessException when the conversion yields more than one instance.
*/
@Nullable
private T extractZeroOrOne(ResultSet rs) throws SQLException {
private <T> T extractZeroOrOne(ResultSet rs, RelationalPersistentEntity<T> entity) throws SQLException {
Iterator<RowDocument> iterate = extractor.iterate(entity, rs);
Iterator<RowDocument> iterate = extractor.iterate(aggregate, rs);
if (iterate.hasNext()) {
RowDocument object = iterate.next();
if (iterate.hasNext()) {
throw new IncorrectResultSizeDataAccessException(1);
}
return converter.read(aggregate.getType(), object);
return converter.read(entity.getType(), object);
}
return null;
}

View File

@@ -25,9 +25,7 @@ import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.core.sqlgeneration.AliasFactory;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.util.ConcurrentLruCache;
/**
* A {@link ReadingDataAccessStrategy} that uses an {@link AggregateReader} to load entities with a single query.
@@ -39,31 +37,28 @@ import org.springframework.util.ConcurrentLruCache;
class SingleQueryDataAccessStrategy implements ReadingDataAccessStrategy {
private final RelationalMappingContext mappingContext;
private final AliasFactory aliasFactory;
private final ConcurrentLruCache<RelationalPersistentEntity<?>, AggregateReader<?>> readerCache;
private final AggregateReader aggregateReader;
public SingleQueryDataAccessStrategy(Dialect dialect, JdbcConverter converter,
NamedParameterJdbcOperations jdbcTemplate) {
this.mappingContext = converter.getMappingContext();
this.aliasFactory = new AliasFactory();
this.readerCache = new ConcurrentLruCache<>(256,
entity -> new AggregateReader<>(dialect, converter, aliasFactory, jdbcTemplate, entity));
this.aggregateReader = new AggregateReader(dialect, converter, jdbcTemplate);
}
@Override
public <T> T findById(Object id, Class<T> domainType) {
return getReader(domainType).findById(id);
return aggregateReader.findById(id, getPersistentEntity(domainType));
}
@Override
public <T> List<T> findAll(Class<T> domainType) {
return getReader(domainType).findAll();
return aggregateReader.findAll(getPersistentEntity(domainType));
}
@Override
public <T> List<T> findAllById(Iterable<?> ids, Class<T> domainType) {
return getReader(domainType).findAllById(ids);
return aggregateReader.findAllById(ids, getPersistentEntity(domainType));
}
@Override
@@ -78,12 +73,12 @@ class SingleQueryDataAccessStrategy implements ReadingDataAccessStrategy {
@Override
public <T> Optional<T> findOne(Query query, Class<T> domainType) {
return Optional.ofNullable(getReader(domainType).findOne(query));
return Optional.ofNullable(aggregateReader.findOne(query, getPersistentEntity(domainType)));
}
@Override
public <T> List<T> findAll(Query query, Class<T> domainType) {
return getReader(domainType).findAll(query);
return aggregateReader.findAll(query, getPersistentEntity(domainType));
}
@Override
@@ -92,11 +87,7 @@ class SingleQueryDataAccessStrategy implements ReadingDataAccessStrategy {
}
@SuppressWarnings("unchecked")
private <T> AggregateReader<T> getReader(Class<T> domainType) {
RelationalPersistentEntity<T> persistentEntity = (RelationalPersistentEntity<T>) mappingContext
.getRequiredPersistentEntity(domainType);
return (AggregateReader<T>) readerCache.get(persistentEntity);
private <T> RelationalPersistentEntity<T> getPersistentEntity(Class<T> domainType) {
return (RelationalPersistentEntity<T>) mappingContext.getRequiredPersistentEntity(domainType);
}
}

View File

@@ -18,12 +18,9 @@ package org.springframework.data.jdbc.core;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.SoftAssertions.*;
import static org.springframework.data.jdbc.testing.TestConfiguration.*;
import static org.springframework.data.jdbc.testing.TestDatabaseFeatures.Feature.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,8 +35,6 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.IntStream;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@@ -47,7 +42,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.annotation.Id;
@@ -74,7 +68,6 @@ import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.CriteriaDefinition;
import org.springframework.data.relational.core.query.Query;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
@@ -191,11 +184,11 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
private static LegoSet createLegoSet(String name) {
LegoSet entity = new LegoSet();
entity.name = (name);
entity.name = name;
Manual manual = new Manual();
manual.content = ("Accelerates to 99% of light speed; Destroys almost everything. See https://what-if.xkcd.com/1/");
entity.manual = (manual);
manual.content = "Accelerates to 99% of light speed; Destroys almost everything. See https://what-if.xkcd.com/1/";
entity.manual = manual;
return entity;
}
@@ -304,13 +297,10 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
assertThat(reloadedLegoSet.manual).isNotNull();
assertSoftly(softly -> {
softly.assertThat(reloadedLegoSet.manual.id) //
.isEqualTo(legoSet.manual.id) //
.isNotNull();
softly.assertThat(reloadedLegoSet.manual.content).isEqualTo(legoSet.manual.content);
});
assertThat(reloadedLegoSet.manual.id) //
.isEqualTo(legoSet.manual.id) //
.isNotNull();
assertThat(reloadedLegoSet.manual.content).isEqualTo(legoSet.manual.content);
}
@Test // DATAJDBC-112
@@ -378,7 +368,6 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
assertThatThrownBy(() -> template.findAll(LegoSet.class, Sort.by("somethingNotExistant")))
.isInstanceOf(InvalidPersistentPropertyPath.class);
}
@Test // DATAJDBC-112
@@ -397,7 +386,7 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
@EnabledOnFeature(SUPPORTS_QUOTED_IDS)
void saveAndLoadAnEntityWithReferencedNullEntity() {
legoSet.manual = (null);
legoSet.manual = null;
template.save(legoSet);
@@ -414,11 +403,8 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.delete(legoSet);
assertSoftly(softly -> {
softly.assertThat(template.findAll(LegoSet.class)).isEmpty();
softly.assertThat(template.findAll(Manual.class)).isEmpty();
});
assertThat(template.findAll(LegoSet.class)).isEmpty();
assertThat(template.findAll(Manual.class)).isEmpty();
}
@Test // DATAJDBC-112
@@ -429,12 +415,8 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.deleteAll(LegoSet.class);
assertSoftly(softly -> {
softly.assertThat(template.findAll(LegoSet.class)).isEmpty();
softly.assertThat(template.findAll(Manual.class)).isEmpty();
});
assertThat(template.findAll(LegoSet.class)).isEmpty();
assertThat(template.findAll(Manual.class)).isEmpty();
}
@Test // GH-537
@@ -447,11 +429,8 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.deleteAll(List.of(legoSet1, legoSet2));
assertSoftly(softly -> {
softly.assertThat(template.findAll(LegoSet.class)).extracting(l -> l.name).containsExactly("Some other Name");
softly.assertThat(template.findAll(Manual.class)).hasSize(1);
});
assertThat(template.findAll(LegoSet.class)).extracting(l -> l.name).containsExactly("Some other Name");
assertThat(template.findAll(Manual.class)).hasSize(1);
}
@Test // GH-537
@@ -464,11 +443,8 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.deleteAllById(List.of(legoSet1.id, legoSet2.id), LegoSet.class);
assertSoftly(softly -> {
softly.assertThat(template.findAll(LegoSet.class)).extracting(l -> l.name).containsExactly("Some other Name");
softly.assertThat(template.findAll(Manual.class)).hasSize(1);
});
assertThat(template.findAll(LegoSet.class)).extracting(l -> l.name).containsExactly("Some other Name");
assertThat(template.findAll(Manual.class)).hasSize(1);
}
@Test
@@ -525,9 +501,9 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.save(legoSet);
Manual manual = new Manual();
manual.id = (23L);
manual.content = ("Some content");
legoSet.manual = (manual);
manual.id = 23L;
manual.content = "Some content";
legoSet.manual = manual;
template.save(legoSet);
@@ -542,18 +518,14 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.save(legoSet);
legoSet.manual = (null);
legoSet.manual = null;
template.save(legoSet);
LegoSet reloadedLegoSet = template.findById(legoSet.id, LegoSet.class);
SoftAssertions softly = new SoftAssertions();
softly.assertThat(reloadedLegoSet.manual).isNull();
softly.assertThat(template.findAll(Manual.class)).describedAs("Manuals failed to delete").isEmpty();
softly.assertAll();
assertThat(reloadedLegoSet.manual).isNull();
assertThat(template.findAll(Manual.class)).describedAs("Manuals failed to delete").isEmpty();
}
@Test
@@ -561,7 +533,7 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
void updateFailedRootDoesNotExist() {
LegoSet entity = new LegoSet();
entity.id = (100L); // does not exist in the database
entity.id = 100L; // does not exist in the database
assertThatExceptionOfType(DbActionExecutionException.class) //
.isThrownBy(() -> template.save(entity)) //
@@ -575,18 +547,15 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.save(legoSet);
Manual manual = new Manual();
manual.content = ("other content");
legoSet.manual = (manual);
manual.content = "other content";
legoSet.manual = manual;
template.save(legoSet);
LegoSet reloadedLegoSet = template.findById(legoSet.id, LegoSet.class);
assertSoftly(softly -> {
softly.assertThat(reloadedLegoSet.manual.content).isEqualTo("other content");
softly.assertThat(template.findAll(Manual.class)).describedAs("There should be only one manual").hasSize(1);
});
assertThat(reloadedLegoSet.manual.content).isEqualTo("other content");
assertThat(template.findAll(Manual.class)).describedAs("There should be only one manual").hasSize(1);
}
@Test // DATAJDBC-112
@@ -595,7 +564,7 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
template.save(legoSet);
legoSet.manual.content = ("new content");
legoSet.manual.content = "new content";
template.save(legoSet);
@@ -678,14 +647,11 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
LegoSet reloadedLegoSet = template.findById(legoSet.id, LegoSet.class);
assertSoftly(softly -> {
softly.assertThat(reloadedLegoSet.alternativeInstructions).isNotNull();
softly.assertThat(reloadedLegoSet.alternativeInstructions.id).isNotNull();
softly.assertThat(reloadedLegoSet.alternativeInstructions.id).isNotEqualTo(reloadedLegoSet.manual.id);
softly.assertThat(reloadedLegoSet.alternativeInstructions.content)
.isEqualTo(reloadedLegoSet.alternativeInstructions.content);
});
assertThat(reloadedLegoSet.alternativeInstructions).isNotNull();
assertThat(reloadedLegoSet.alternativeInstructions.id).isNotNull();
assertThat(reloadedLegoSet.alternativeInstructions.id).isNotEqualTo(reloadedLegoSet.manual.id);
assertThat(reloadedLegoSet.alternativeInstructions.content)
.isEqualTo(reloadedLegoSet.alternativeInstructions.content);
}
@Test // DATAJDBC-276
@@ -927,14 +893,11 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
NoIdListChain4 saved = template.save(createNoIdTree());
template.deleteById(saved.four, NoIdListChain4.class);
assertSoftly(softly -> {
softly.assertThat(count("NO_ID_LIST_CHAIN4")).describedAs("Chain4 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_LIST_CHAIN3")).describedAs("Chain3 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_LIST_CHAIN2")).describedAs("Chain2 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_LIST_CHAIN1")).describedAs("Chain1 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_LIST_CHAIN0")).describedAs("Chain0 elements got deleted").isEqualTo(0);
});
assertThat(count("NO_ID_LIST_CHAIN4")).describedAs("Chain4 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_LIST_CHAIN3")).describedAs("Chain3 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_LIST_CHAIN2")).describedAs("Chain2 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_LIST_CHAIN1")).describedAs("Chain1 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_LIST_CHAIN0")).describedAs("Chain0 elements got deleted").isEqualTo(0);
}
@Test
@@ -956,14 +919,11 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
NoIdMapChain4 saved = template.save(createNoIdMapTree());
template.deleteById(saved.four, NoIdMapChain4.class);
assertSoftly(softly -> {
softly.assertThat(count("NO_ID_MAP_CHAIN4")).describedAs("Chain4 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_MAP_CHAIN3")).describedAs("Chain3 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_MAP_CHAIN2")).describedAs("Chain2 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_MAP_CHAIN1")).describedAs("Chain1 elements got deleted").isEqualTo(0);
softly.assertThat(count("NO_ID_MAP_CHAIN0")).describedAs("Chain0 elements got deleted").isEqualTo(0);
});
assertThat(count("NO_ID_MAP_CHAIN4")).describedAs("Chain4 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_MAP_CHAIN3")).describedAs("Chain3 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_MAP_CHAIN2")).describedAs("Chain2 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_MAP_CHAIN1")).describedAs("Chain1 elements got deleted").isEqualTo(0);
assertThat(count("NO_ID_MAP_CHAIN0")).describedAs("Chain0 elements got deleted").isEqualTo(0);
}
@Test // DATAJDBC-431
@@ -978,7 +938,7 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
assertThat(
jdbcTemplate.queryForObject("SELECT read_only FROM with_read_only", Collections.emptyMap(), String.class))
.isEqualTo("from-db");
.isEqualTo("from-db");
}
@Test
@@ -1230,21 +1190,17 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
MultipleCollections reloaded = template.findById(aggregate.id, MultipleCollections.class);
assertSoftly(softly -> {
assertThat(reloaded.name).isEqualTo(aggregate.name);
softly.assertThat(reloaded.name).isEqualTo(aggregate.name);
assertThat(reloaded.listElements).containsExactly(aggregate.listElements.get(0), aggregate.listElements.get(1),
aggregate.listElements.get(2));
softly.assertThat(reloaded.listElements).containsExactly(aggregate.listElements.get(0),
aggregate.listElements.get(1), aggregate.listElements.get(2));
assertThat(reloaded.setElements).containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.setElements)
.containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
softly.assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
softly.assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
softly.assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
});
assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
}
@Test // GH-1448
@@ -1266,21 +1222,17 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
MultipleCollections reloaded = template.findById(aggregate.id, MultipleCollections.class);
assertSoftly(softly -> {
assertThat(reloaded.name).isEqualTo(aggregate.name);
softly.assertThat(reloaded.name).isEqualTo(aggregate.name);
assertThat(reloaded.listElements).containsExactly(aggregate.listElements.get(0), aggregate.listElements.get(1),
aggregate.listElements.get(2));
softly.assertThat(reloaded.listElements).containsExactly(aggregate.listElements.get(0),
aggregate.listElements.get(1), aggregate.listElements.get(2));
assertThat(reloaded.setElements).containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.setElements)
.containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
softly.assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
softly.assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
softly.assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
});
assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
}
@Test // GH-1448
@@ -1301,20 +1253,16 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
MultipleCollections reloaded = template.findById(aggregate.id, MultipleCollections.class);
assertSoftly(softly -> {
assertThat(reloaded.name).isEqualTo(aggregate.name);
softly.assertThat(reloaded.name).isEqualTo(aggregate.name);
assertThat(reloaded.listElements).containsExactly();
softly.assertThat(reloaded.listElements).containsExactly();
assertThat(reloaded.setElements).containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.setElements)
.containsExactlyInAnyOrder(aggregate.setElements.toArray(new SetElement[0]));
softly.assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
softly.assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
softly.assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
softly.assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
});
assertThat(reloaded.mapElements.get("alpha")).isEqualTo(new MapElement("one"));
assertThat(reloaded.mapElements.get("beta")).isEqualTo(new MapElement("two"));
assertThat(reloaded.mapElements.get("gamma")).isEqualTo(new MapElement("three"));
assertThat(reloaded.mapElements.get("delta")).isEqualTo(new MapElement("four"));
}
private <T extends Number> void saveAndUpdateAggregateWithVersion(VersionedAggregate aggregate,

View File

@@ -29,7 +29,6 @@ import java.util.Set;
import java.util.stream.Stream;
import org.assertj.core.api.Assertions;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -441,7 +440,6 @@ class StringBasedJdbcQueryUnitTests {
this.values = List.of(values);
}
@NotNull
@Override
public Iterator<String> iterator() {
return values.iterator();
@@ -460,7 +458,7 @@ class StringBasedJdbcQueryUnitTests {
}
private static class DummyEntity {
private Long id;
private final Long id;
public DummyEntity(Long id) {
this.id = id;
@@ -488,6 +486,7 @@ class StringBasedJdbcQueryUnitTests {
}
}
@Override
public Object getRootObject() {
return new ExtensionRoot();
}