diff --git a/pom.xml b/pom.xml index 8f9de8fe20..762448b140 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-jdbc - 1.0.0.BUILD-SNAPSHOT + 1.0.0.DATAJDBC-98-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -67,6 +67,11 @@ spring-beans + + org.springframework + spring-jdbc + + org.springframework spring-core @@ -84,9 +89,12 @@ 2.2.8 test + - org.springframework - spring-jdbc + org.assertj + assertj-core + 3.6.2 + test diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java index 7e91a166c9..bbe2d69cfc 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java @@ -19,11 +19,39 @@ import org.springframework.data.util.TypeInformation; /** + * meta data a repository might need for implementing persistence operations for instances of type {@code T} * @author Jens Schauder */ public class JdbcPersistentEntity extends BasicPersistentEntity { + private String tableName; + private String idColumn; + public JdbcPersistentEntity(TypeInformation information) { super(information); } + + public String getTableName() { + + if (tableName == null) + tableName = getType().getSimpleName(); + + return tableName; + } + + public String getIdColumn() { + + if (idColumn == null) + idColumn = getIdProperty().getName(); + + return idColumn; + } + + public Object getIdValue(T instance) { + return getPropertyAccessor(instance).getProperty(getIdProperty()); + } + + public void setId(T instance, Object value) { + getPropertyAccessor(instance).setProperty(getIdProperty(),value); + } } diff --git a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java index 1bcc1be849..841d64c650 100644 --- a/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java +++ b/src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentProperty.java @@ -23,6 +23,8 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; /** + * meta data about a property to be used by repository implementations. + * * @author Jens Schauder */ public class JdbcPersistentProperty extends AnnotationBasedPersistentProperty { @@ -43,4 +45,8 @@ public JdbcPersistentProperty(Field field, PropertyDescriptor propertyDescriptor protected Association createAssociation() { return null; } + + public String getColumnName() { + return getName(); + } } diff --git a/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java b/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java new file mode 100644 index 0000000000..4bde019f07 --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/repository/EntityRowMapper.java @@ -0,0 +1,78 @@ +/* + * Copyright 2017 the original author or 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 + * + * http://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 org.springframework.data.jdbc.repository; + +import java.sql.ResultSet; +import java.sql.SQLException; +import org.springframework.data.convert.ClassGeneratingEntityInstantiator; +import org.springframework.data.convert.EntityInstantiator; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; +import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.mapping.PreferredConstructor; +import org.springframework.data.mapping.PropertyHandler; +import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.model.ParameterValueProvider; + +/** + * maps a ResultSet to an entity of type {@code T} + * + * @author Jens Schauder + */ +class EntityRowMapper implements org.springframework.jdbc.core.RowMapper { + + private final JdbcPersistentEntity entity; + + private final EntityInstantiator instantiator = new ClassGeneratingEntityInstantiator(); + + EntityRowMapper(JdbcPersistentEntity entity) { + this.entity = entity; + } + + @Override + public T mapRow(ResultSet rs, int rowNum) throws SQLException { + + T t = createInstance(rs); + + entity.doWithProperties((PropertyHandler) property -> { + setProperty(rs, t, property); + }); + + return t; + } + + private T createInstance(ResultSet rs) { + return instantiator.createInstance(entity, new ParameterValueProvider() { + @Override + public T getParameterValue(PreferredConstructor.Parameter parameter) { + try { + return (T) rs.getObject(parameter.getName()); + } catch (SQLException e) { + throw new MappingException(String.format("Couldn't read column %s from ResultSet.", parameter.getName())); + } + } + }); + } + + private void setProperty(ResultSet rs, T t, PersistentProperty property) { + + try { + entity.getPropertyAccessor(t).setProperty(property, rs.getObject(property.getName())); + } catch (Exception e) { + throw new RuntimeException(String.format("Couldn't set property %s.", property.getName()), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java b/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java index 45bb7ad979..8ec48d2d51 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java +++ b/src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java @@ -18,85 +18,149 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import javax.sql.DataSource; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty; +import org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInformation; +import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.core.EntityInformation; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; /** * @author Jens Schauder */ public class SimpleJdbcRepository implements CrudRepository { - private final EntityInformation entityInformation; + private final JdbcPersistentEntity entity; + private final JdbcPersistentEntityInformation entityInformation; private final NamedParameterJdbcOperations template; + private final SqlGenerator sql; - public SimpleJdbcRepository(EntityInformation entityInformation, DataSource dataSource) { - this.entityInformation = entityInformation; + private final EntityRowMapper entityRowMapper; + + public SimpleJdbcRepository(JdbcPersistentEntity entity, DataSource dataSource) { + + this.entity = entity; + this.entityInformation = new JdbcPersistentEntityInformation(entity); this.template = new NamedParameterJdbcTemplate(dataSource); + + entityRowMapper = new EntityRowMapper(entity); + sql = new SqlGenerator(entity); } @Override - public S save(S entity) { - Map parameters = new HashMap<>(); - parameters.put("id", entityInformation.getId(entity)); - parameters.put("name", "blah blah"); + public S save(S instance) { - template.update( - "insert into dummyentity (id, name) values (:id, :name)", - parameters); + if (entityInformation.isNew(instance)) { - return entity; + KeyHolder holder = new GeneratedKeyHolder(); + + template.update( + sql.getInsert(), + new MapSqlParameterSource(getPropertyMap(instance)), + holder); + + entity.setId(instance, holder.getKey()); + } else { + template.update(sql.getUpdate(), getPropertyMap(instance)); + } + + return instance; } @Override public Iterable save(Iterable entities) { - return null; + + entities.forEach(this::save); + + return entities; } @Override public T findOne(ID id) { - return null; + + return template.queryForObject( + sql.getFindOne(), + new MapSqlParameterSource("id", id), + entityRowMapper + ); } @Override public boolean exists(ID id) { - return false; + + return template.queryForObject( + sql.getExists(), + new MapSqlParameterSource("id", id), + Boolean.class + ); } @Override public Iterable findAll() { - return null; + return template.query(sql.getFindAll(), entityRowMapper); } @Override public Iterable findAll(Iterable ids) { - return null; + return template.query(sql.getFindAllInList(), new MapSqlParameterSource("ids", ids), entityRowMapper); } @Override public long count() { - return 0; + return template.getJdbcOperations().queryForObject(sql.getCount(), Long.class); } @Override public void delete(ID id) { - + template.update(sql.getDeleteById(), new MapSqlParameterSource("id", id)); } @Override - public void delete(T entity) { + public void delete(T instance) { + template.update( + sql.getDeleteById(), + new MapSqlParameterSource("id", + entity.getIdValue(instance))); } @Override public void delete(Iterable entities) { + template.update( + sql.getDeleteByList(), + new MapSqlParameterSource("ids", + StreamSupport + .stream(entities.spliterator(), false) + .map(entity::getIdValue) + .collect(Collectors.toList()) + ) + ); } @Override public void deleteAll() { + template.getJdbcOperations().update(sql.getDeleteAll()); + } + + private Map getPropertyMap(final S instance) { + + Map parameters = new HashMap<>(); + + this.entity.doWithProperties(new PropertyHandler() { + @Override + public void doWithPersistentProperty(JdbcPersistentProperty persistentProperty) { + parameters.put(persistentProperty.getColumnName(), entity.getPropertyAccessor(instance).getProperty(persistentProperty)); + } + }); + return parameters; } } diff --git a/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java b/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java new file mode 100644 index 0000000000..2d613d78a6 --- /dev/null +++ b/src/main/java/org/springframework/data/jdbc/repository/SqlGenerator.java @@ -0,0 +1,153 @@ +/* + * Copyright 2017 the original author or 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 + * + * http://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 org.springframework.data.jdbc.repository; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; +import org.springframework.data.mapping.PropertyHandler; + +/** + * @author Jens Schauder + */ +class SqlGenerator { + + private final String findOneSql; + private final String findAllSql; + private final String findAllInListSql; + + private final String existsSql; + private final String countSql; + + private final String insertSql; + private final String deleteByIdSql; + private final String deleteAllSql; + private final String deleteByListSql; + private final String updateSql; + private final List propertyNames = new ArrayList<>(); + + SqlGenerator(JdbcPersistentEntity entity) { + + entity.doWithProperties((PropertyHandler) persistentProperty -> propertyNames.add(persistentProperty.getName())); + + findOneSql = createFindOneSelectSql(entity); + findAllSql = createFindAllSql(entity); + findAllInListSql = createFindAllInListSql(entity); + + existsSql = createExistsSql(entity); + countSql = createCountSql(entity); + + insertSql = createInsertSql(entity); + updateSql = createUpdateSql(entity); + + deleteByIdSql = createDeleteSql(entity); + deleteAllSql = createDeleteAllSql(entity); + deleteByListSql = createDeleteByListSql(entity); + } + + String getFindAllInList() { + return findAllInListSql; + } + + String getFindAll() { + return findAllSql; + } + + String getExists() { + return existsSql; + } + + String getFindOne() { + return findOneSql; + } + + String getInsert() { + return insertSql; + } + + String getUpdate() { + return updateSql; + } + + String getCount() { + return countSql; + } + + String getDeleteById() { + return deleteByIdSql; + } + + String getDeleteAll() { + return deleteAllSql; + } + + String getDeleteByList() { + return deleteByListSql; + } + private String createFindOneSelectSql(JdbcPersistentEntity entity) { + return String.format("select * from %s where %s = :id", entity.getTableName(), entity.getIdColumn()); + } + + private String createFindAllSql(JdbcPersistentEntity entity) { + return String.format("select * from %s", entity.getTableName()); + } + + private String createFindAllInListSql(JdbcPersistentEntity entity) { + return String.format(String.format("select * from %s where %s in (:ids)", entity.getTableName(), entity.getIdColumn()), entity.getTableName()); + } + + private String createExistsSql(JdbcPersistentEntity entity) { + return String.format("select count(*) from %s where %s = :id", entity.getTableName(), entity.getIdColumn()); + } + + private String createCountSql(JdbcPersistentEntity entity) { + return String.format("select count(*) from %s", entity.getTableName()); + } + + private String createInsertSql(JdbcPersistentEntity entity) { + + String insertTemplate = "insert into %s (%s) values (%s)"; + + String tableColumns = propertyNames.stream().collect(Collectors.joining(", ")); + String parameterNames = propertyNames.stream().collect(Collectors.joining(", :", ":", "")); + + return String.format(insertTemplate, entity.getTableName(), tableColumns, parameterNames); + } + + private String createUpdateSql(JdbcPersistentEntity entity) { + + String updateTemplate = "update %s set %s where %s = :%s"; + + String setClause = propertyNames.stream().map(n -> String.format("%s = :%s", n, n)).collect(Collectors.joining(", ")); + + return String.format(updateTemplate, entity.getTableName(), setClause, entity.getIdColumn(), entity.getIdColumn()); + } + + private String createDeleteSql(JdbcPersistentEntity entity) { + return String.format("delete from %s where %s = :id", entity.getTableName(), entity.getIdColumn()); + } + + private String createDeleteAllSql(JdbcPersistentEntity entity) { + return String.format("delete from %s", entity.getTableName()); + } + + private String createDeleteByListSql(JdbcPersistentEntity entity) { + return String.format("delete from %s where %s in (:ids)", entity.getTableName(), entity.getIdColumn()); + } + +} diff --git a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java index a92d74d6cb..d24598250d 100644 --- a/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java +++ b/src/main/java/org/springframework/data/jdbc/repository/support/JdbcRepositoryFactory.java @@ -39,13 +39,12 @@ public JdbcRepositoryFactory(DataSource dataSource) { @Override public EntityInformation getEntityInformation(Class aClass) { - JdbcPersistentEntity persistentEntity = (JdbcPersistentEntity) context.getPersistentEntity(aClass); - return new JdbcPersistentEntityInformation(persistentEntity); + return new JdbcPersistentEntityInformation((JdbcPersistentEntity) context.getPersistentEntity(aClass)); } @Override protected Object getTargetRepository(RepositoryInformation repositoryInformation) { - return new SimpleJdbcRepository(getEntityInformation(repositoryInformation.getDomainType()), dataSource); + return new SimpleJdbcRepository(context.getPersistentEntity(repositoryInformation.getDomainType()), dataSource); } @Override diff --git a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java new file mode 100644 index 0000000000..2f2b5396a8 --- /dev/null +++ b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIdGenerationIntegrationTests.java @@ -0,0 +1,129 @@ +/* + * Copyright 2017 the original author or 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 + * + * http://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 org.springframework.data.jdbc.repository; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Test; +import org.springframework.data.annotation.Id; +import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; +import org.springframework.data.repository.CrudRepository; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +import lombok.Data; + +/** + * testing special cases for Id generation with JdbcRepositories. + * + * @author Jens Schauder + */ +public class JdbcRepositoryIdGenerationIntegrationTests { + + private final EmbeddedDatabase db = new EmbeddedDatabaseBuilder() + .generateUniqueName(true) + .setType(EmbeddedDatabaseType.HSQL) + .setScriptEncoding("UTF-8") + .ignoreFailedDrops(true) + .addScript("org.springframework.data.jdbc.repository/jdbc-repository-id-generation-integration-tests.sql") + .build(); + + private final NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(db); + + private final ReadOnlyIdEntityRepository repository = createRepository(db); + + private ReadOnlyIdEntity entity = createDummyEntity(); + + @After + public void after() { + db.shutdown(); + } + + @Test + public void idWithoutSetterGetsSet() { + + entity = repository.save(entity); + + assertThat(entity.getId()).isNotNull(); + + ReadOnlyIdEntity reloadedEntity = repository.findOne(entity.getId()); + + assertEquals( + entity.getId(), + reloadedEntity.getId()); + assertEquals( + entity.getName(), + reloadedEntity.getName()); + } + + @Test + public void primitiveIdGetsSet() { + + entity = repository.save(entity); + + assertThat(entity.getId()).isNotNull(); + + ReadOnlyIdEntity reloadedEntity = repository.findOne(entity.getId()); + + assertEquals( + entity.getId(), + reloadedEntity.getId()); + assertEquals( + entity.getName(), + reloadedEntity.getName()); + } + + + private static ReadOnlyIdEntityRepository createRepository(EmbeddedDatabase db) { + return new JdbcRepositoryFactory(db).getRepository(ReadOnlyIdEntityRepository.class); + } + + + private static ReadOnlyIdEntity createDummyEntity() { + + ReadOnlyIdEntity entity = new ReadOnlyIdEntity(null); + entity.setName("Entity Name"); + return entity; + } + + private interface ReadOnlyIdEntityRepository extends CrudRepository { + + } + + @Data + static class ReadOnlyIdEntity { + + @Id + private final Long id; + String name; + } + + private interface PrimitiveIdEntityRepository extends CrudRepository { + + } + + @Data + static class PrimitiveIdEntity { + + @Id + private final Long id; + String name; + } +} diff --git a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index b938925f62..410b92fbd6 100644 --- a/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -15,9 +15,10 @@ */ package org.springframework.data.jdbc.repository; +import static java.util.Arrays.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; -import java.sql.SQLException; import org.junit.After; import org.junit.Test; import org.springframework.data.annotation.Id; @@ -43,30 +44,29 @@ public class JdbcRepositoryIntegrationTests { .setType(EmbeddedDatabaseType.HSQL) .setScriptEncoding("UTF-8") .ignoreFailedDrops(true) - .addScript("org.springframework.data.jdbc.repository/createTable.sql") + .addScript("org.springframework.data.jdbc.repository/jdbc-repository-integration-tests.sql") .build(); private final NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(db); + private final DummyEntityRepository repository = createRepository(db); + + private DummyEntity entity = createDummyEntity(); + @After - public void afeter() { + public void after() { db.shutdown(); } @Test - public void canSaveAnEntity() throws SQLException { - DummyEntityRepository repository = createRepository(); - - DummyEntity entity = new DummyEntity(); - entity.setId(23L); - entity.setName("Entity Name"); + public void canSaveAnEntity() { entity = repository.save(entity); int count = template.queryForObject( - "SELECT count(*) FROM dummyentity WHERE id = :id", - new MapSqlParameterSource("id", entity.getId()), + "SELECT count(*) FROM dummyentity WHERE idProp = :id", + new MapSqlParameterSource("id", entity.getIdProp()), Integer.class); assertEquals( @@ -74,9 +74,167 @@ public void canSaveAnEntity() throws SQLException { count); } - private DummyEntityRepository createRepository() throws SQLException { - JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory(db); - return jdbcRepositoryFactory.getRepository(DummyEntityRepository.class); + @Test + public void canSaveAndLoadAnEntity() { + + entity = repository.save(entity); + + DummyEntity reloadedEntity = repository.findOne(entity.getIdProp()); + + assertEquals( + entity.getIdProp(), + reloadedEntity.getIdProp()); + assertEquals( + entity.getName(), + reloadedEntity.getName()); + } + + @Test + public void saveMany() { + + DummyEntity other = createDummyEntity(); + + repository.save(asList(entity, other)); + + assertThat(repository.findAll()).extracting(DummyEntity::getIdProp).containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp()); + } + + @Test + public void existsReturnsTrueIffEntityExists() { + + entity = repository.save(entity); + + assertTrue(repository.exists(entity.getIdProp())); + assertFalse(repository.exists(entity.getIdProp() + 1)); + } + + @Test + public void findAllFindsAllEntities() { + + DummyEntity other = createDummyEntity(); + + other = repository.save(other); + entity = repository.save(entity); + + Iterable all = repository.findAll(); + + assertThat(all).extracting("idProp").containsExactlyInAnyOrder(entity.getIdProp(), other.getIdProp()); + } + + @Test + public void findAllFindsAllSpecifiedEntities() { + + DummyEntity two = repository.save(createDummyEntity()); + DummyEntity three = repository.save(createDummyEntity()); + entity = repository.save(entity); + + Iterable all = repository.findAll(asList(entity.getIdProp(), three.getIdProp())); + + assertThat(all).extracting("idProp").containsExactlyInAnyOrder(entity.getIdProp(), three.getIdProp()); + } + + @Test + public void count() { + + repository.save(createDummyEntity()); + repository.save(createDummyEntity()); + repository.save(entity); + + assertThat(repository.count()).isEqualTo(3L); + } + + @Test + public void deleteById() { + + entity = repository.save(entity); + DummyEntity two = repository.save(createDummyEntity()); + DummyEntity three = repository.save(createDummyEntity()); + + repository.delete(two.getIdProp()); + + assertThat(repository.findAll()) + .extracting(DummyEntity::getIdProp) + .containsExactlyInAnyOrder(entity.getIdProp(), three.getIdProp()); + } + + @Test + public void deleteByEntity() { + + entity = repository.save(entity); + DummyEntity two = repository.save(createDummyEntity()); + DummyEntity three = repository.save(createDummyEntity()); + + repository.delete(entity); + + assertThat(repository.findAll()).extracting(DummyEntity::getIdProp).containsExactlyInAnyOrder(two.getIdProp(), three.getIdProp()); + } + + + @Test + public void deleteByList() { + + repository.save(entity); + DummyEntity two = repository.save(createDummyEntity()); + DummyEntity three = repository.save(createDummyEntity()); + + repository.delete(asList(entity, three)); + + assertThat(repository.findAll()).extracting(DummyEntity::getIdProp).containsExactlyInAnyOrder(two.getIdProp()); + } + + @Test + public void deleteAll() { + + repository.save(entity); + repository.save(createDummyEntity()); + repository.save(createDummyEntity()); + + repository.deleteAll(); + + assertThat(repository.findAll()).isEmpty(); + } + + + @Test + public void update() { + + entity = repository.save(entity); + + entity.setName("something else"); + + entity = repository.save(entity); + + DummyEntity reloaded = repository.findOne(entity.getIdProp()); + + assertThat(reloaded.getName()).isEqualTo(entity.getName()); + } + + @Test + public void updateMany() { + + entity = repository.save(entity); + DummyEntity other = repository.save(createDummyEntity()); + + entity.setName("something else"); + other.setName("others Name"); + + repository.save(asList(entity, other)); + + assertThat(repository.findAll()) + .extracting(DummyEntity::getName) + .containsExactlyInAnyOrder(entity.getName(), other.getName()); + } + + private static DummyEntityRepository createRepository(EmbeddedDatabase db) { + return new JdbcRepositoryFactory(db).getRepository(DummyEntityRepository.class); + } + + + private static DummyEntity createDummyEntity() { + + DummyEntity entity = new DummyEntity(); + entity.setName("Entity Name"); + return entity; } private interface DummyEntityRepository extends CrudRepository { @@ -84,10 +242,10 @@ private interface DummyEntityRepository extends CrudRepository