DATAJDBC-96 - Database based ID generation.
No longer using batch inserts, which won't (easily) hold up for long anyway, since we need to decide between update and insert anyway. If one wants to support batch insert one also has to check if any autoid columns are present, because those seem not to work with batch inserts with many or at least some drivers. Related ticket: SPR-1836. Original pull request: #5.
This commit is contained in:
committed by
Oliver Gierke
parent
2181d8d3c6
commit
21490b8397
@@ -50,4 +50,8 @@ public class JdbcPersistentEntity<T> extends BasicPersistentEntity<T, JdbcPersis
|
||||
public Object getIdValue(T instance) {
|
||||
return getPropertyAccessor(instance).getProperty(getIdProperty());
|
||||
}
|
||||
|
||||
public void setId(T instance, Object value) {
|
||||
getPropertyAccessor(instance).setProperty(getIdProperty(),value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.springframework.data.repository.CrudRepository;
|
||||
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
|
||||
@@ -50,22 +52,24 @@ public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRep
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends T> S save(S entity) {
|
||||
public <S extends T> S save(S instance) {
|
||||
|
||||
template.update(sql.getInsert(), getPropertyMap(entity));
|
||||
KeyHolder holder = new GeneratedKeyHolder();
|
||||
|
||||
return entity;
|
||||
template.update(
|
||||
sql.getInsert(),
|
||||
new MapSqlParameterSource(getPropertyMap(instance)),
|
||||
holder);
|
||||
|
||||
entity.setId(instance, holder.getKey());
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends T> Iterable<S> save(Iterable<S> entities) {
|
||||
|
||||
Map<String, ?>[] batchValues = StreamSupport
|
||||
.stream(entities.spliterator(), false)
|
||||
.map(i -> getPropertyMap(i))
|
||||
.toArray(size -> new Map[size]);
|
||||
|
||||
template.batchUpdate(sql.getInsert(), batchValues);
|
||||
entities.forEach(this::save);
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ 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.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
|
||||
@@ -91,6 +89,26 @@ public class JdbcRepositoryIntegrationTests {
|
||||
reloadedEntity.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canSaveAndLoadAnEntityWithDatabaseBasedIdGeneration() {
|
||||
|
||||
entity = createDummyEntity(null);
|
||||
|
||||
entity = repository.save(entity);
|
||||
|
||||
assertThat(entity).isNotNull();
|
||||
|
||||
DummyEntity reloadedEntity = repository.findOne(entity.getId());
|
||||
|
||||
assertEquals(
|
||||
entity.getId(),
|
||||
reloadedEntity.getId());
|
||||
assertEquals(
|
||||
entity.getName(),
|
||||
reloadedEntity.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void saveMany() {
|
||||
|
||||
@@ -101,6 +119,21 @@ public class JdbcRepositoryIntegrationTests {
|
||||
assertThat(repository.findAll()).extracting(DummyEntity::getId).containsExactlyInAnyOrder(23L, 24L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveManyWithIdGeneration() {
|
||||
|
||||
DummyEntity one = createDummyEntity(null);
|
||||
DummyEntity two = createDummyEntity(null);
|
||||
|
||||
Iterable<DummyEntity> entities = repository.save(asList(one, two));
|
||||
|
||||
assertThat(entities).allMatch(e -> e.getId() != null);
|
||||
|
||||
assertThat(repository.findAll())
|
||||
.extracting(DummyEntity::getId)
|
||||
.containsExactlyInAnyOrder(new Long[]{one.getId(), two.getId()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existsReturnsTrueIffEntityExists() {
|
||||
|
||||
@@ -195,13 +228,12 @@ public class JdbcRepositoryIntegrationTests {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static DummyEntityRepository createRepository(EmbeddedDatabase db) {
|
||||
return new JdbcRepositoryFactory(db).getRepository(DummyEntityRepository.class);
|
||||
}
|
||||
|
||||
|
||||
private static DummyEntity createDummyEntity(long id) {
|
||||
private static DummyEntity createDummyEntity(Long id) {
|
||||
|
||||
DummyEntity entity = new DummyEntity();
|
||||
entity.setId(id);
|
||||
|
||||
@@ -1 +1 @@
|
||||
CREATE TABLE dummyentity (ID BIGINT, NAME VARCHAR(100), PRIMARY KEY (ID))
|
||||
CREATE TABLE dummyentity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 4711) PRIMARY KEY, NAME VARCHAR(100))
|
||||
Reference in New Issue
Block a user