Skip to content

Commit a390cf7

Browse files
committed
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.
1 parent 85d165c commit a390cf7

File tree

4 files changed

+54
-14
lines changed

4 files changed

+54
-14
lines changed

src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,8 @@ public String getIdColumn() {
5050
public Object getIdValue(T instance) {
5151
return getPropertyAccessor(instance).getProperty(getIdProperty());
5252
}
53+
54+
public void setId(T instance, Object value) {
55+
getPropertyAccessor(instance).setProperty(getIdProperty(),value);
56+
}
5357
}

src/main/java/org/springframework/data/jdbc/repository/SimpleJdbcRepository.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
2929
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
3030
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
31+
import org.springframework.jdbc.support.GeneratedKeyHolder;
32+
import org.springframework.jdbc.support.KeyHolder;
3133

3234
/**
3335
* @author Jens Schauder
@@ -50,22 +52,24 @@ public SimpleJdbcRepository(JdbcPersistentEntity<T> entity, DataSource dataSourc
5052
}
5153

5254
@Override
53-
public <S extends T> S save(S entity) {
55+
public <S extends T> S save(S instance) {
5456

55-
template.update(sql.getInsert(), getPropertyMap(entity));
57+
KeyHolder holder = new GeneratedKeyHolder();
5658

57-
return entity;
59+
template.update(
60+
sql.getInsert(),
61+
new MapSqlParameterSource(getPropertyMap(instance)),
62+
holder);
63+
64+
entity.setId(instance, holder.getKey());
65+
66+
return instance;
5867
}
5968

6069
@Override
6170
public <S extends T> Iterable<S> save(Iterable<S> entities) {
6271

63-
Map<String, ?>[] batchValues = StreamSupport
64-
.stream(entities.spliterator(), false)
65-
.map(i -> getPropertyMap(i))
66-
.toArray(size -> new Map[size]);
67-
68-
template.batchUpdate(sql.getInsert(), batchValues);
72+
entities.forEach(this::save);
6973

7074
return entities;
7175
}

src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
import static org.assertj.core.api.Assertions.assertThat;
2020
import static org.junit.Assert.*;
2121

22-
import java.sql.SQLException;
2322
import org.junit.After;
24-
import org.junit.Assert;
2523
import org.junit.Test;
2624
import org.springframework.data.annotation.Id;
2725
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
@@ -91,6 +89,26 @@ public void canSaveAndLoadAnEntity() {
9189
reloadedEntity.getName());
9290
}
9391

92+
@Test
93+
public void canSaveAndLoadAnEntityWithDatabaseBasedIdGeneration() {
94+
95+
entity = createDummyEntity(null);
96+
97+
entity = repository.save(entity);
98+
99+
assertThat(entity).isNotNull();
100+
101+
DummyEntity reloadedEntity = repository.findOne(entity.getId());
102+
103+
assertEquals(
104+
entity.getId(),
105+
reloadedEntity.getId());
106+
assertEquals(
107+
entity.getName(),
108+
reloadedEntity.getName());
109+
}
110+
111+
94112
@Test
95113
public void saveMany() {
96114

@@ -101,6 +119,21 @@ public void saveMany() {
101119
assertThat(repository.findAll()).extracting(DummyEntity::getId).containsExactlyInAnyOrder(23L, 24L);
102120
}
103121

122+
@Test
123+
public void saveManyWithIdGeneration() {
124+
125+
DummyEntity one = createDummyEntity(null);
126+
DummyEntity two = createDummyEntity(null);
127+
128+
Iterable<DummyEntity> entities = repository.save(asList(one, two));
129+
130+
assertThat(entities).allMatch(e -> e.getId() != null);
131+
132+
assertThat(repository.findAll())
133+
.extracting(DummyEntity::getId)
134+
.containsExactlyInAnyOrder(new Long[]{one.getId(), two.getId()});
135+
}
136+
104137
@Test
105138
public void existsReturnsTrueIffEntityExists() {
106139

@@ -195,13 +228,12 @@ public void deleteAll() {
195228
}
196229

197230

198-
199231
private static DummyEntityRepository createRepository(EmbeddedDatabase db) {
200232
return new JdbcRepositoryFactory(db).getRepository(DummyEntityRepository.class);
201233
}
202234

203235

204-
private static DummyEntity createDummyEntity(long id) {
236+
private static DummyEntity createDummyEntity(Long id) {
205237

206238
DummyEntity entity = new DummyEntity();
207239
entity.setId(id);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
CREATE TABLE dummyentity (ID BIGINT, NAME VARCHAR(100), PRIMARY KEY (ID))
1+
CREATE TABLE dummyentity (ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 4711) PRIMARY KEY, NAME VARCHAR(100))

0 commit comments

Comments
 (0)