Browse Source

DATAJDBC-112 - Processing feedback from review.

Code formatting. Removed few superfluous lines of code.

Renamed JdbcInterpreter to DefaultJdbcInterpreter.
The prefix Jdbc doesn't really carry much information in the SD JDBC project.

Renamed jdbcConverter fields to jdbcEntityWriter in order to match the type names.

Renamed DbChange to AggregateChange.
It isn't really about the database but about the aggregate.
pull/9/merge
Jens Schauder 9 years ago committed by Greg Turnquist
parent
commit
c55dd9e177
No known key found for this signature in database
GPG Key ID: CB2FA4D512B5C413
  1. 5
      src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java
  2. 11
      src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java
  3. 8
      src/main/java/org/springframework/data/jdbc/core/JdbcEntityOperations.java
  4. 66
      src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java
  5. 25
      src/main/java/org/springframework/data/jdbc/core/SelectBuilder.java
  6. 5
      src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java
  7. 4
      src/main/java/org/springframework/data/jdbc/core/conversion/AggregateChange.java
  8. 6
      src/main/java/org/springframework/data/jdbc/core/conversion/Interpreter.java
  9. 22
      src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriter.java
  10. 39
      src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriter.java
  11. 14
      src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterSupport.java
  12. 4
      src/main/java/org/springframework/data/jdbc/mapping/model/PropertyPaths.java
  13. 2
      src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java
  14. 39
      src/test/java/org/springframework/data/jdbc/core/JdbcEntityTemplateIntegrationTests.java
  15. 8
      src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java
  16. 20
      src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java

5
src/main/java/org/springframework/data/jdbc/core/JdbcInterpreter.java → src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java

@ -35,12 +35,13 @@ import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; @@ -35,12 +35,13 @@ import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
*
* @author Jens Schauder
*/
class JdbcInterpreter implements Interpreter {
class DefaultJdbcInterpreter implements Interpreter {
private final JdbcMappingContext context;
private final JdbcEntityTemplate template;
JdbcInterpreter(JdbcMappingContext context, JdbcEntityTemplate template) {
DefaultJdbcInterpreter(JdbcMappingContext context, JdbcEntityTemplate template) {
this.context = context;
this.template = template;
}

11
src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java

@ -75,8 +75,11 @@ class EntityRowMapper<T> implements RowMapper<T> { @@ -75,8 +75,11 @@ class EntityRowMapper<T> implements RowMapper<T> {
private Object readFrom(ResultSet resultSet, JdbcPersistentProperty property, String prefix) {
try {
if (property.isEntity())
if (property.isEntity()) {
return readEntityFrom(resultSet, property);
}
return resultSet.getObject(prefix + property.getColumnName());
} catch (SQLException o_O) {
throw new MappingException(String.format("Could not read property %s from result set!", property), o_O);
@ -90,8 +93,9 @@ class EntityRowMapper<T> implements RowMapper<T> { @@ -90,8 +93,9 @@ class EntityRowMapper<T> implements RowMapper<T> {
@SuppressWarnings("unchecked")
JdbcPersistentEntity<S> entity = (JdbcPersistentEntity<S>) context.getRequiredPersistentEntity(property.getType());
if (readFrom(rs, entity.getRequiredIdProperty(), prefix) == null)
if (readFrom(rs, entity.getRequiredIdProperty(), prefix) == null) {
return null;
}
S instance = instantiator.createInstance(entity, ResultSetParameterValueProvider.of(rs, conversions, prefix));
@ -120,8 +124,9 @@ class EntityRowMapper<T> implements RowMapper<T> { @@ -120,8 +124,9 @@ class EntityRowMapper<T> implements RowMapper<T> {
public <T> T getParameterValue(Parameter<T, JdbcPersistentProperty> parameter) {
String name = parameter.getName();
if (name == null)
if (name == null) {
return null;
}
try {
return conversionService.convert(resultSet.getObject(prefix + name), parameter.getType().getType());

8
src/main/java/org/springframework/data/jdbc/core/JdbcEntityOperations.java

@ -24,6 +24,8 @@ import java.util.Map; @@ -24,6 +24,8 @@ import java.util.Map;
*/
public interface JdbcEntityOperations {
<T> void save(T instance, Class<T> domainType);
<T> void insert(T instance, Class<T> domainType, Map<String, Object> additionalParameter);
<T> void update(T instance, Class<T> domainType);
@ -32,6 +34,8 @@ public interface JdbcEntityOperations { @@ -32,6 +34,8 @@ public interface JdbcEntityOperations {
<T> void delete(T entity, Class<T> domainType);
void deleteAll(Class<?> domainType);
long count(Class<?> domainType);
<T> T findById(Object id, Class<T> domainType);
@ -41,8 +45,4 @@ public interface JdbcEntityOperations { @@ -41,8 +45,4 @@ public interface JdbcEntityOperations {
<T> Iterable<T> findAll(Class<T> domainType);
<T> boolean existsById(Object id, Class<T> domainType);
void deleteAll(Class<?> domainType);
<T> void save(T instance, Class<T> domainType);
}

66
src/main/java/org/springframework/data/jdbc/core/JdbcEntityTemplate.java

@ -28,11 +28,11 @@ import org.springframework.core.convert.support.GenericConversionService; @@ -28,11 +28,11 @@ import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.data.convert.Jsr310Converters;
import org.springframework.data.jdbc.core.conversion.DbChange;
import org.springframework.data.jdbc.core.conversion.DbChange.Kind;
import org.springframework.data.jdbc.core.conversion.AggregateChange;
import org.springframework.data.jdbc.core.conversion.AggregateChange.Kind;
import org.springframework.data.jdbc.core.conversion.Interpreter;
import org.springframework.data.jdbc.core.conversion.JdbcEntityWriter;
import org.springframework.data.jdbc.core.conversion.JdbcEntityDeleteWriter;
import org.springframework.data.jdbc.core.conversion.JdbcEntityWriter;
import org.springframework.data.jdbc.mapping.event.AfterDelete;
import org.springframework.data.jdbc.mapping.event.AfterInsert;
import org.springframework.data.jdbc.mapping.event.AfterUpdate;
@ -63,7 +63,7 @@ import org.springframework.util.Assert; @@ -63,7 +63,7 @@ import org.springframework.util.Assert;
public class JdbcEntityTemplate implements JdbcEntityOperations {
private static final String ENTITY_NEW_AFTER_INSERT = "Entity [%s] still 'new' after insert. Please set either"
+ " the id property in a before insert event handler, or ensure the database creates a value and your "
+ " the id property in a BeforeInsert event handler, or ensure the database creates a value and your "
+ "JDBC driver returns it.";
private final ApplicationEventPublisher publisher;
@ -73,8 +73,8 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -73,8 +73,8 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
private final Interpreter interpreter;
private final SqlGeneratorSource sqlGeneratorSource;
private final JdbcEntityWriter jdbcConverter;
private final JdbcEntityDeleteWriter jdbcEntityDeleteConverter;
private final JdbcEntityWriter jdbcEntityWriter;
private final JdbcEntityDeleteWriter jdbcEntityDeleteWriter;
public JdbcEntityTemplate(ApplicationEventPublisher publisher, NamedParameterJdbcOperations operations,
JdbcMappingContext context) {
@ -83,10 +83,10 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -83,10 +83,10 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
this.operations = operations;
this.context = context;
jdbcConverter = new JdbcEntityWriter(this.context);
jdbcEntityDeleteConverter = new JdbcEntityDeleteWriter(this.context);
sqlGeneratorSource = new SqlGeneratorSource(this.context);
interpreter = new JdbcInterpreter(this.context, this);
this.jdbcEntityWriter = new JdbcEntityWriter(this.context);
this.jdbcEntityDeleteWriter = new JdbcEntityDeleteWriter(this.context);
this.sqlGeneratorSource = new SqlGeneratorSource(this.context);
this.interpreter = new DefaultJdbcInterpreter(this.context, this);
}
private static GenericConversionService getDefaultConversionService() {
@ -99,11 +99,11 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -99,11 +99,11 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
@Override
public <T> void save(T instance, Class<T> domainType) {
createDbChange(instance).executeWith(interpreter);
createChange(instance).executeWith(interpreter);
}
@Override
public <T> void insert(T instance, Class<T> domainType, Map<String, Object> additionalParameter) {
public <T> void insert(T instance, Class<T> domainType, Map<String, Object> additionalParameters) {
publisher.publishEvent(new BeforeInsert(instance));
@ -118,9 +118,9 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -118,9 +118,9 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
JdbcPersistentProperty idProperty = persistentEntity.getRequiredIdProperty();
propertyMap.put(idProperty.getColumnName(), convert(idValue, idProperty.getColumnType()));
propertyMap.putAll(additionalParameter);
propertyMap.putAll(additionalParameters);
operations.update(sql(domainType).getInsert(idValue == null, additionalParameter.keySet()),
operations.update(sql(domainType).getInsert(idValue == null, additionalParameters.keySet()),
new MapSqlParameterSource(propertyMap), holder);
setIdFromJdbc(instance, holder, persistentEntity);
@ -177,8 +177,13 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -177,8 +177,13 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
String findAllInListSql = sql(domainType).getFindAllInList();
Class<?> targetType = getRequiredPersistentEntity(domainType).getRequiredIdProperty().getColumnType();
MapSqlParameterSource parameter = new MapSqlParameterSource("ids",
StreamSupport.stream(ids.spliterator(), false).map(id -> convert(id, targetType)).collect(Collectors.toList()));
MapSqlParameterSource parameter = new MapSqlParameterSource( //
"ids", //
StreamSupport.stream(ids.spliterator(), false) //
.map(id -> convert(id, targetType)) //
.collect(Collectors.toList()) //
);
return operations.query(findAllInListSql, parameter, getEntityRowMapper(domainType));
}
@ -199,7 +204,7 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -199,7 +204,7 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
@Override
public void deleteAll(Class<?> domainType) {
DbChange change = createDeletingDbChange(domainType);
AggregateChange change = createDeletingChange(domainType);
change.executeWith(interpreter);
}
@ -225,7 +230,6 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -225,7 +230,6 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
publisher.publishEvent(new BeforeDelete(specifiedId, optionalEntity));
String deleteByIdSql = sql(domainType).getDeleteById();
MapSqlParameterSource parameter = createIdParameterSource(specifiedId.getValue(), domainType);
operations.update(deleteByIdSql, parameter);
@ -235,30 +239,30 @@ public class JdbcEntityTemplate implements JdbcEntityOperations { @@ -235,30 +239,30 @@ public class JdbcEntityTemplate implements JdbcEntityOperations {
private void deleteTree(Object id, Object entity, Class<?> domainType) {
DbChange change = createDeletingDbChange(id, entity, domainType);
AggregateChange change = createDeletingChange(id, entity, domainType);
change.executeWith(interpreter);
}
private <T> DbChange createDbChange(T instance) {
private <T> AggregateChange createChange(T instance) {
DbChange dbChange = new DbChange(Kind.SAVE, instance.getClass(), instance);
jdbcConverter.write(instance, dbChange);
return dbChange;
AggregateChange aggregateChange = new AggregateChange(Kind.SAVE, instance.getClass(), instance);
jdbcEntityWriter.write(instance, aggregateChange);
return aggregateChange;
}
private DbChange createDeletingDbChange(Object id, Object entity, Class<?> domainType) {
private AggregateChange createDeletingChange(Object id, Object entity, Class<?> domainType) {
DbChange dbChange = new DbChange(Kind.DELETE, domainType, entity);
jdbcEntityDeleteConverter.write(id, dbChange);
return dbChange;
AggregateChange aggregateChange = new AggregateChange(Kind.DELETE, domainType, entity);
jdbcEntityDeleteWriter.write(id, aggregateChange);
return aggregateChange;
}
private DbChange createDeletingDbChange(Class<?> domainType) {
private AggregateChange createDeletingChange(Class<?> domainType) {
DbChange dbChange = new DbChange(Kind.DELETE, domainType, null);
jdbcEntityDeleteConverter.write(null, dbChange);
return dbChange;
AggregateChange aggregateChange = new AggregateChange(Kind.DELETE, domainType, null);
jdbcEntityDeleteWriter.write(null, aggregateChange);
return aggregateChange;
}
private <T> MapSqlParameterSource createIdParameterSource(Object id, Class<T> domainType) {

25
src/main/java/org/springframework/data/jdbc/core/SelectBuilder.java

@ -47,11 +47,13 @@ class SelectBuilder { @@ -47,11 +47,13 @@ class SelectBuilder {
}
SelectBuilder where(Function<WhereConditionBuilder, WhereConditionBuilder> whereSpec) {
conditions.add(whereSpec.apply(new WhereConditionBuilder(this)).build());
return this;
}
SelectBuilder join(Function<Join.JoinBuilder, Join.JoinBuilder> joinSpec) {
joins.add(joinSpec.apply(Join.builder()).build());
return this;
}
@ -62,9 +64,15 @@ class SelectBuilder { @@ -62,9 +64,15 @@ class SelectBuilder {
}
private String whereClause() {
if (conditions.isEmpty())
if (conditions.isEmpty()) {
return "";
return conditions.stream().map(wc -> wc.toSql()).collect(Collectors.joining("AND", " WHERE ", ""));
}
return conditions.stream() //
.map(WhereCondition::toSql) //
.collect(Collectors.joining("AND", " WHERE ", "") //
);
}
private String joinClause() {
@ -76,13 +84,16 @@ class SelectBuilder { @@ -76,13 +84,16 @@ class SelectBuilder {
}
private String joinConditions(Join j) {
return j.conditions.stream().map(w -> String.format("%s %s %s", w.fromExpression, w.operation, w.toExpression))
return j.conditions.stream() //
.map(w -> String.format("%s %s %s", w.fromExpression, w.operation, w.toExpression)) //
.collect(Collectors.joining(" AND ", " ON ", ""));
}
private String selectFrom() {
return columns.stream() //
.map(c -> c.columnDefinition()) //
.map(Column::columnDefinition) //
.collect(Collectors.joining(", ", "SELECT ", " FROM " + tableName));
}
@ -101,13 +112,13 @@ class SelectBuilder { @@ -101,13 +112,13 @@ class SelectBuilder {
WhereConditionBuilder eq() {
operation = "=";
this.operation = "=";
return this;
}
public WhereConditionBuilder in() {
operation = "in";
this.operation = "in";
return this;
}
@ -125,7 +136,7 @@ class SelectBuilder { @@ -125,7 +136,7 @@ class SelectBuilder {
WhereConditionBuilder variable(String var) {
expression = ":" + var;
this.expression = ":" + var;
return this;
}

5
src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java

@ -158,7 +158,9 @@ class SqlGenerator { @@ -158,7 +158,9 @@ class SqlGenerator {
}
private Stream<String> getColumnNameStream(String prefix) {
return StreamUtils.createStreamFromIterator(entity.iterator()).flatMap(p -> getColumnNameStream(p, prefix));
return StreamUtils.createStreamFromIterator(entity.iterator()) //
.flatMap(p -> getColumnNameStream(p, prefix));
}
private Stream<String> getColumnNameStream(JdbcPersistentProperty p, String prefix) {
@ -216,6 +218,7 @@ class SqlGenerator { @@ -216,6 +218,7 @@ class SqlGenerator {
}
String createDeleteAllSql(PropertyPath path) {
if (path == null) {
return String.format("DELETE FROM %s", entity.getTableName());
}

4
src/main/java/org/springframework/data/jdbc/core/conversion/DbChange.java → src/main/java/org/springframework/data/jdbc/core/conversion/AggregateChange.java

@ -22,11 +22,13 @@ import java.util.ArrayList; @@ -22,11 +22,13 @@ import java.util.ArrayList;
import java.util.List;
/**
* Represents the change happening to the aggregate (as used in the context of Domain Driven Design) as a whole.
*
* @author Jens Schauder
*/
@RequiredArgsConstructor
@Getter
public class DbChange<T> {
public class AggregateChange<T> {
private final Kind kind;

6
src/main/java/org/springframework/data/jdbc/core/conversion/Interpreter.java

@ -25,9 +25,11 @@ import org.springframework.data.jdbc.core.conversion.DbAction.Update; @@ -25,9 +25,11 @@ import org.springframework.data.jdbc.core.conversion.DbAction.Update;
*/
public interface Interpreter {
<T>void interpret(Update<T> update);
<T>void interpret(Insert<T> insert);
<T> void interpret(Update<T> update);
<T> void interpret(Insert<T> insert);
<T> void interpret(Delete<T> delete);
<T> void interpret(DeleteAll<T> delete);
}

22
src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriter.java

@ -19,7 +19,7 @@ import org.springframework.data.jdbc.mapping.model.JdbcMappingContext; @@ -19,7 +19,7 @@ import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
import org.springframework.data.jdbc.mapping.model.PropertyPaths;
/**
* Converts an entity that is about to be deleted into {@link DbAction}s inside a {@link DbChange} that need to be
* Converts an entity that is about to be deleted into {@link DbAction}s inside a {@link AggregateChange} that need to be
* executed against the database to recreate the appropriate state in the database.
*
* @author Jens Schauder
@ -31,28 +31,28 @@ public class JdbcEntityDeleteWriter extends JdbcEntityWriterSupport { @@ -31,28 +31,28 @@ public class JdbcEntityDeleteWriter extends JdbcEntityWriterSupport {
}
@Override
public void write(Object id, DbChange dbChange) {
public void write(Object id, AggregateChange aggregateChange) {
if (id == null) {
deleteAll(dbChange);
deleteAll(aggregateChange);
} else {
deleteById(id, dbChange);
deleteById(id, aggregateChange);
}
}
private void deleteAll(DbChange dbChange) {
private void deleteAll(AggregateChange aggregateChange) {
context.referencedEntities(dbChange.getEntityType(), null)
.forEach(p -> dbChange.addAction(DbAction.deleteAll(PropertyPaths.getLeafType(p), p, null)));
context.referencedEntities(aggregateChange.getEntityType(), null)
.forEach(p -> aggregateChange.addAction(DbAction.deleteAll(PropertyPaths.getLeafType(p), p, null)));
dbChange.addAction(DbAction.deleteAll(dbChange.getEntityType(), null, null));
aggregateChange.addAction(DbAction.deleteAll(aggregateChange.getEntityType(), null, null));
}
private void deleteById(Object id, DbChange dbChange) {
private void deleteById(Object id, AggregateChange aggregateChange) {
deleteReferencedEntities(id, dbChange);
deleteReferencedEntities(id, aggregateChange);
dbChange.addAction(DbAction.delete(id, dbChange.getEntityType(), dbChange.getEntity(), null, null));
aggregateChange.addAction(DbAction.delete(id, aggregateChange.getEntityType(), aggregateChange.getEntity(), null, null));
}
}

39
src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriter.java

@ -28,7 +28,7 @@ import org.springframework.data.mapping.PersistentPropertyAccessor; @@ -28,7 +28,7 @@ import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.util.StreamUtils;
/**
* Converts an entity that is about to be saved into {@link DbAction}s inside a {@link DbChange} that need to be
* Converts an entity that is about to be saved into {@link DbAction}s inside a {@link AggregateChange} that need to be
* executed against the database to recreate the appropriate state in the database.
*
* @author Jens Schauder
@ -40,39 +40,40 @@ public class JdbcEntityWriter extends JdbcEntityWriterSupport { @@ -40,39 +40,40 @@ public class JdbcEntityWriter extends JdbcEntityWriterSupport {
}
@Override
public void write(Object o, DbChange dbChange) {
write(o, dbChange, null);
public void write(Object o, AggregateChange aggregateChange) {
write(o, aggregateChange, null);
}
private void write(Object o, DbChange dbChange, DbAction dependingOn) {
private void write(Object o, AggregateChange aggregateChange, DbAction dependingOn) {
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(dbChange.getEntityType());
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(aggregateChange.getEntityType());
JdbcPersistentEntityInformation<Object, ?> entityInformation = context
.getRequiredPersistentEntityInformation((Class<Object>) o.getClass());
if (entityInformation.isNew(o)) {
Insert<Object> insert = DbAction.insert(o, dependingOn);
dbChange.addAction(insert);
aggregateChange.addAction(insert);
referencedEntities(o).forEach(e -> saveReferencedEntities(e, dbChange, insert));
referencedEntities(o).forEach(e -> saveReferencedEntities(e, aggregateChange, insert));
} else {
deleteReferencedEntities(entityInformation.getRequiredId(o), dbChange);
deleteReferencedEntities(entityInformation.getRequiredId(o), aggregateChange);
Update<Object> update = DbAction.update(o, dependingOn);
dbChange.addAction(update);
aggregateChange.addAction(update);
referencedEntities(o).forEach(e -> insertReferencedEntities(e, dbChange, update));
referencedEntities(o).forEach(e -> insertReferencedEntities(e, aggregateChange, update));
}
}
private void saveReferencedEntities(Object o, DbChange dbChange, DbAction dependingOn) {
private void saveReferencedEntities(Object o, AggregateChange aggregateChange, DbAction dependingOn) {
DbAction action = saveAction(o, dependingOn);
dbChange.addAction(action);
aggregateChange.addAction(action);
referencedEntities(o).forEach(e -> saveReferencedEntities(e, dbChange, action));
referencedEntities(o).forEach(e -> saveReferencedEntities(e, aggregateChange, action));
}
private <T> DbAction saveAction(T t, DbAction dependingOn) {
@ -80,17 +81,17 @@ public class JdbcEntityWriter extends JdbcEntityWriterSupport { @@ -80,17 +81,17 @@ public class JdbcEntityWriter extends JdbcEntityWriterSupport {
JdbcPersistentEntityInformation<T, ?> entityInformation = context
.getRequiredPersistentEntityInformation((Class<T>) t.getClass());
if (entityInformation.isNew(t))
if (entityInformation.isNew(t)) {
return DbAction.insert(t, dependingOn);
else
} else {
return DbAction.update(t, dependingOn);
}
}
private void insertReferencedEntities(Object o, DbChange dbChange, DbAction dependingOn) {
private void insertReferencedEntities(Object o, AggregateChange aggregateChange, DbAction dependingOn) {
System.out.println("adding an insert");
dbChange.addAction(DbAction.insert(o, dependingOn));
referencedEntities(o).forEach(e -> insertReferencedEntities(e, dbChange, dependingOn));
aggregateChange.addAction(DbAction.insert(o, dependingOn));
referencedEntities(o).forEach(e -> insertReferencedEntities(e, aggregateChange, dependingOn));
}
private Stream<Object> referencedEntities(Object o) {

14
src/main/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterSupport.java

@ -20,11 +20,11 @@ import org.springframework.data.jdbc.mapping.model.JdbcMappingContext; @@ -20,11 +20,11 @@ import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
import org.springframework.data.jdbc.mapping.model.PropertyPaths;
/**
* Common infrastructure needed by different implementations of {@link EntityWriter}<Object, DbChange>.
* Common infrastructure needed by different implementations of {@link EntityWriter}<Object, AggregateChange>.
*
* @author Jens Schauder
*/
abstract class JdbcEntityWriterSupport implements EntityWriter<Object, DbChange> {
abstract class JdbcEntityWriterSupport implements EntityWriter<Object, AggregateChange> {
protected final JdbcMappingContext context;
JdbcEntityWriterSupport(JdbcMappingContext context) {
@ -32,15 +32,15 @@ abstract class JdbcEntityWriterSupport implements EntityWriter<Object, DbChange> @@ -32,15 +32,15 @@ abstract class JdbcEntityWriterSupport implements EntityWriter<Object, DbChange>
}
/**
* add {@link org.springframework.data.jdbc.core.conversion.DbAction.Delete} actions to the {@link DbChange} for
* add {@link org.springframework.data.jdbc.core.conversion.DbAction.Delete} actions to the {@link AggregateChange} for
* deleting all referenced entities.
*
* @param id id of the aggregate root, of which the referenced entities get deleted.
* @param dbChange the change object to which the actions should get added. Must not be {@literal null}
* @param aggregateChange the change object to which the actions should get added. Must not be {@literal null}
*/
void deleteReferencedEntities(Object id, DbChange dbChange) {
void deleteReferencedEntities(Object id, AggregateChange aggregateChange) {
context.referencedEntities(dbChange.getEntityType(), null)
.forEach(p -> dbChange.addAction(DbAction.delete(id, PropertyPaths.getLeafType(p), null, p, null)));
context.referencedEntities(aggregateChange.getEntityType(), null)
.forEach(p -> aggregateChange.addAction(DbAction.delete(id, PropertyPaths.getLeafType(p), null, p, null)));
}
}

4
src/main/java/org/springframework/data/jdbc/mapping/model/PropertyPaths.java

@ -29,8 +29,10 @@ import org.springframework.util.Assert; @@ -29,8 +29,10 @@ import org.springframework.util.Assert;
public class PropertyPaths {
public static Class<?> getLeafType(PropertyPath path) {
if (path.hasNext())
if (path.hasNext()) {
return getLeafType(path.next());
}
return path.getType();
}

2
src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java

@ -46,8 +46,6 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport { @@ -46,8 +46,6 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> aClass) {
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(aClass);
if (persistentEntity == null)
return null;
return new BasicJdbcPersistentEntityInformation<>((JdbcPersistentEntity<T>) persistentEntity);
}

39
src/test/java/org/springframework/data/jdbc/core/JdbcEntityTemplateIntegrationTests.java

@ -47,26 +47,8 @@ import org.springframework.transaction.annotation.Transactional; @@ -47,26 +47,8 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional
public class JdbcEntityTemplateIntegrationTests {
@Configuration
@Import(TestConfiguration.class)
static class Config {
@Bean
Class<?> testClass() {
return JdbcEntityTemplateIntegrationTests.class;
}
@Bean
JdbcEntityOperations operations(ApplicationEventPublisher publisher,
NamedParameterJdbcOperations namedParameterJdbcOperations) {
return new JdbcEntityTemplate(publisher, namedParameterJdbcOperations, new JdbcMappingContext());
}
}
@ClassRule public static final SpringClassRule classRule = new SpringClassRule();
@Rule public SpringMethodRule methodRule = new SpringMethodRule();
@Autowired JdbcEntityOperations template;
LegoSet legoSet = createLegoSet();
@ -247,12 +229,31 @@ public class JdbcEntityTemplateIntegrationTests { @@ -247,12 +229,31 @@ public class JdbcEntityTemplateIntegrationTests {
private String name;
private Manual manual;
}
@Data
static class Manual {
@Id private final Long id;
@Id private final Long id;
private String content;
}
@Configuration
@Import(TestConfiguration.class)
static class Config {
@Bean
Class<?> testClass() {
return JdbcEntityTemplateIntegrationTests.class;
}
@Bean
JdbcEntityOperations operations(ApplicationEventPublisher publisher,
NamedParameterJdbcOperations namedParameterJdbcOperations) {
return new JdbcEntityTemplate(publisher, namedParameterJdbcOperations, new JdbcMappingContext());
}
}
}

8
src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityDeleteWriterUnitTests.java

@ -23,8 +23,8 @@ import org.junit.Test; @@ -23,8 +23,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.conversion.AggregateChange.Kind;
import org.springframework.data.jdbc.core.conversion.DbAction.Delete;
import org.springframework.data.jdbc.core.conversion.DbChange.Kind;
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
/**
@ -42,11 +42,11 @@ public class JdbcEntityDeleteWriterUnitTests { @@ -42,11 +42,11 @@ public class JdbcEntityDeleteWriterUnitTests {
SomeEntity entity = new SomeEntity(23L);
DbChange<SomeEntity> dbChange = new DbChange(Kind.DELETE, SomeEntity.class, entity);
AggregateChange<SomeEntity> aggregateChange = new AggregateChange(Kind.DELETE, SomeEntity.class, entity);
converter.write(entity, dbChange);
converter.write(entity, aggregateChange);
Assertions.assertThat(dbChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType)
Assertions.assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType)
.containsExactly( //
Tuple.tuple(Delete.class, YetAnother.class), //
Tuple.tuple(Delete.class, OtherEntity.class), //

20
src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java

@ -23,10 +23,10 @@ import org.junit.Test; @@ -23,10 +23,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.conversion.AggregateChange.Kind;
import org.springframework.data.jdbc.core.conversion.DbAction.Delete;
import org.springframework.data.jdbc.core.conversion.DbAction.Insert;
import org.springframework.data.jdbc.core.conversion.DbAction.Update;
import org.springframework.data.jdbc.core.conversion.DbChange.Kind;
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
/**
@ -43,10 +43,10 @@ public class JdbcEntityWriterUnitTests { @@ -43,10 +43,10 @@ public class JdbcEntityWriterUnitTests {
public void newEntityGetsConvertedToOneInsert() {
SomeEntity entity = new SomeEntity(null);
DbChange<SomeEntity> dbChange = new DbChange(Kind.SAVE, SomeEntity.class, entity);
converter.write(entity, dbChange);
AggregateChange<SomeEntity> aggregateChange = new AggregateChange(Kind.SAVE, SomeEntity.class, entity);
converter.write(entity, aggregateChange);
assertThat(dbChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
.containsExactly( //
tuple(Insert.class, SomeEntity.class) //
);
@ -57,11 +57,11 @@ public class JdbcEntityWriterUnitTests { @@ -57,11 +57,11 @@ public class JdbcEntityWriterUnitTests {
SomeEntity entity = new SomeEntity(23L);
DbChange<SomeEntity> dbChange = new DbChange(Kind.SAVE, SomeEntity.class, entity);
AggregateChange<SomeEntity> aggregateChange = new AggregateChange(Kind.SAVE, SomeEntity.class, entity);
converter.write(entity, dbChange);
converter.write(entity, aggregateChange);
assertThat(dbChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
.containsExactly( //
tuple(Delete.class, OtherEntity.class), //
tuple(Update.class, SomeEntity.class) //
@ -74,11 +74,11 @@ public class JdbcEntityWriterUnitTests { @@ -74,11 +74,11 @@ public class JdbcEntityWriterUnitTests {
SomeEntity entity = new SomeEntity(23L);
entity.setOther(new OtherEntity(null));
DbChange<SomeEntity> dbChange = new DbChange(Kind.SAVE, SomeEntity.class, entity);
AggregateChange<SomeEntity> aggregateChange = new AggregateChange(Kind.SAVE, SomeEntity.class, entity);
converter.write(entity, dbChange);
converter.write(entity, aggregateChange);
assertThat(dbChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
assertThat(aggregateChange.getActions()).extracting(DbAction::getClass, DbAction::getEntityType) //
.containsExactly( //
tuple(Delete.class, OtherEntity.class), //
tuple(Update.class, SomeEntity.class), //

Loading…
Cancel
Save