Skip to content

Commit 4515d6b

Browse files
Merge pull request #179 from xdev-software/develop
v2.3.1
2 parents 093ed2f + 2a91265 commit 4515d6b

File tree

6 files changed

+239
-8
lines changed

6 files changed

+239
-8
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
# 2.3.1
2+
3+
* Auto-Fix problems with adding ids to entities with existing data store.
4+
15
# 2.3.0
26

3-
* Add support for shuting down the storage during application shutdown
4-
* By default only enabled when Spring DevTools are active
7+
* Add support for shutting down the storage during application shutdown
8+
* By default, only enabled when Spring DevTools are active
59
* This should fix "StorageExceptionInitialization: Active storage for ... already exists" errors during DevTools restart
610
* Added [Jakarta Bean Validation Constraints](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/beanvalidation/bean-validation/bean-validation.html#_using_jakarta_bean_validation_constraints) with Hibernate validator for entities.
711

docs/antora.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
name: ROOT
22
title: Spring-Data-Eclipse-Store
33
version: master
4-
display_version: '2.3.0'
4+
display_version: '2.3.1'
55
start_page: index.adoc
66
nav:
77
- modules/ROOT/nav.adoc
88
asciidoc:
99
attributes:
1010
product-name: 'Spring-Data-Eclipse-Store'
11-
display-version: '2.3.0'
12-
maven-version: '2.3.0'
11+
display-version: '2.3.1'
12+
maven-version: '2.3.1'
1313
page-editable: false
1414
page-out-of-support: false

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/EclipseStoreStorage.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,14 @@ private <T, ID> void setIdManagerForEntityData(final Class<T> entityClass, final
205205
{
206206
final IdManager<T, ID> idManager = this.ensureIdManager(entityClass);
207207
final EntityData<T, Object> entityData = root.getCurrentRootData().getEntityData(entityClass);
208-
entityData.setIdGetter(idManager::getId);
208+
if(idManager.hasIdField())
209+
{
210+
entityData.setIdGetter(idManager::getId);
211+
}
212+
else
213+
{
214+
entityData.setIdGetter(null);
215+
}
209216
}
210217

211218
public synchronized <T> void registerEntity(

spring-data-eclipse-store/src/main/java/software/xdev/spring/data/eclipse/store/repository/root/EntityData.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,27 @@ public EntityData()
4848
this.entitiesById = new HashMap<>();
4949
}
5050

51+
/**
52+
* Accepts {@code null} if no id field is defined
53+
*/
5154
public void setIdGetter(final Function<T, ID> idGetter)
5255
{
5356
this.idGetter = idGetter;
57+
58+
this.ensureEntitiesAndEntitiesByIdAreTheSameSize();
59+
}
60+
61+
private void ensureEntitiesAndEntitiesByIdAreTheSameSize()
62+
{
63+
if(this.idGetter != null && this.entities.size() != this.entitiesById.size())
64+
{
65+
this.entitiesById.clear();
66+
this.entities.forEach(entity -> this.entitiesById.put(this.idGetter.apply(entity), entity));
67+
}
68+
if(this.idGetter == null)
69+
{
70+
this.entitiesById.clear();
71+
}
5472
}
5573

5674
public IdentitySet<T> getEntities()
@@ -83,7 +101,10 @@ public Collection<Object> ensureEntityAndReturnObjectsToStore(final T entityToSt
83101
if(!this.getEntities().contains(entityToStore))
84102
{
85103
this.entities.add(entityToStore);
86-
this.entitiesById.put(this.idGetter.apply(entityToStore), entityToStore);
104+
if(this.idGetter != null)
105+
{
106+
this.entitiesById.put(this.idGetter.apply(entityToStore), entityToStore);
107+
}
87108
return this.getObjectsToStore();
88109
}
89110
return List.of();
@@ -97,7 +118,10 @@ public Collection<Object> getObjectsToStore()
97118
public Collection<Object> removeEntityAndReturnObjectsToStore(final T entityToRemove)
98119
{
99120
this.entities.remove(entityToRemove);
100-
this.entitiesById.remove(this.idGetter.apply(entityToRemove));
121+
if(this.idGetter != null)
122+
{
123+
this.entitiesById.remove(this.idGetter.apply(entityToRemove));
124+
}
101125
return this.getObjectsToStore();
102126
}
103127

spring-data-eclipse-store/src/test/java/software/xdev/spring/data/eclipse/store/integration/isolated/tests/id/IdTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,33 @@ void replaceWithId(@Autowired final CustomerWithIdIntegerNoAutoGenerateRepositor
608608
);
609609
}
610610

611+
@Test
612+
void replaceWithIdAfterRestart(@Autowired final CustomerWithIdIntegerNoAutoGenerateRepository customerRepository)
613+
{
614+
final CustomerWithIdIntegerNoAutoGenerate existingCustomer =
615+
new CustomerWithIdIntegerNoAutoGenerate(1, TestData.FIRST_NAME, TestData.LAST_NAME);
616+
customerRepository.save(existingCustomer);
617+
618+
restartDatastore(this.configuration);
619+
620+
final CustomerWithIdIntegerNoAutoGenerate newCustomer =
621+
new CustomerWithIdIntegerNoAutoGenerate(1, TestData.FIRST_NAME_ALTERNATIVE,
622+
TestData.LAST_NAME_ALTERNATIVE);
623+
customerRepository.save(newCustomer);
624+
625+
TestUtil.doBeforeAndAfterRestartOfDatastore(
626+
this.configuration,
627+
() -> {
628+
final List<CustomerWithIdIntegerNoAutoGenerate> loadedCustomer =
629+
TestUtil.iterableToList(customerRepository.findAll());
630+
631+
Assertions.assertEquals(1, loadedCustomer.size());
632+
Assertions.assertEquals(TestData.FIRST_NAME_ALTERNATIVE, loadedCustomer.get(0).getFirstName());
633+
Assertions.assertEquals(TestData.LAST_NAME_ALTERNATIVE, loadedCustomer.get(0).getLastName());
634+
}
635+
);
636+
}
637+
611638
@Test
612639
void replaceWithAutoId(@Autowired final CustomerWithIdIntegerRepository customerRepository)
613640
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright © 2024 XDEV Software (https://xdev.software)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package software.xdev.spring.data.eclipse.store.repository.root;
17+
18+
import java.util.function.Function;
19+
20+
import org.junit.jupiter.api.Assertions;
21+
import org.junit.jupiter.api.Test;
22+
23+
import software.xdev.spring.data.eclipse.store.helper.TestData;
24+
25+
26+
class EntityDataTest
27+
{
28+
record Person(String id, String name)
29+
{
30+
}
31+
32+
33+
private final Function<Person, String> idGetter = person -> person.id;
34+
private final Function<Person, String> idNullGetter = person -> null;
35+
36+
@Test
37+
void idGetterIsNotSet()
38+
{
39+
final EntityData<Person, String> testData = new EntityData<>();
40+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
41+
Assertions.assertTrue(testData.getEntitiesById().isEmpty());
42+
Assertions.assertEquals(1, testData.getEntities().size());
43+
}
44+
45+
@Test
46+
void idGetterSetAndNothingAdded()
47+
{
48+
final EntityData<Person, String> testData = new EntityData<>();
49+
testData.setIdGetter(this.idGetter);
50+
Assertions.assertTrue(testData.getEntitiesById().isEmpty());
51+
Assertions.assertTrue(testData.getEntities().isEmpty());
52+
}
53+
54+
@Test
55+
void idGetterNotSetSetAndNothingAdded()
56+
{
57+
final EntityData<Person, String> testData = new EntityData<>();
58+
Assertions.assertTrue(testData.getEntitiesById().isEmpty());
59+
Assertions.assertTrue(testData.getEntities().isEmpty());
60+
}
61+
62+
@Test
63+
void idGetterSet()
64+
{
65+
final EntityData<Person, String> testData = new EntityData<>();
66+
testData.setIdGetter(this.idGetter);
67+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
68+
Assertions.assertEquals(1, testData.getEntitiesById().size());
69+
Assertions.assertEquals(1, testData.getEntities().size());
70+
}
71+
72+
@Test
73+
void idGetterSetToNull()
74+
{
75+
final EntityData<Person, String> testData = new EntityData<>();
76+
testData.setIdGetter(this.idNullGetter);
77+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
78+
Assertions.assertEquals(1, testData.getEntitiesById().size());
79+
Assertions.assertEquals(1, testData.getEntities().size());
80+
}
81+
82+
@Test
83+
void idGetterSetToNullWith2Entities()
84+
{
85+
final EntityData<Person, String> testData = new EntityData<>();
86+
testData.setIdGetter(this.idNullGetter);
87+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
88+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
89+
Assertions.assertEquals(1, testData.getEntitiesById().size());
90+
Assertions.assertEquals(2, testData.getEntities().size());
91+
}
92+
93+
@Test
94+
void idGetterSetWith2Entities()
95+
{
96+
final EntityData<Person, String> testData = new EntityData<>();
97+
testData.setIdGetter(this.idGetter);
98+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
99+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
100+
Assertions.assertEquals(2, testData.getEntitiesById().size());
101+
Assertions.assertEquals(2, testData.getEntities().size());
102+
}
103+
104+
@Test
105+
void idGetterFirstNullThenReturningIdSameObject()
106+
{
107+
final EntityData<Person, String> testData = new EntityData<>();
108+
testData.setIdGetter(null);
109+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
110+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
111+
Assertions.assertTrue(testData.getEntitiesById().isEmpty());
112+
Assertions.assertEquals(2, testData.getEntities().size());
113+
114+
testData.setIdGetter(this.idGetter);
115+
final Person foundPerson = testData.getEntities().stream().findFirst().get();
116+
testData.ensureEntityAndReturnObjectsToStore(foundPerson);
117+
Assertions.assertEquals(2, testData.getEntitiesById().size());
118+
Assertions.assertEquals(2, testData.getEntities().size());
119+
}
120+
121+
@Test
122+
void idGetterFirstReturnNullThenReturningIdSameObject()
123+
{
124+
final EntityData<Person, String> testData = new EntityData<>();
125+
testData.setIdGetter(this.idNullGetter);
126+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
127+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
128+
Assertions.assertEquals(1, testData.getEntitiesById().size());
129+
Assertions.assertEquals(2, testData.getEntities().size());
130+
131+
testData.setIdGetter(this.idGetter);
132+
final Person foundPerson = testData.getEntities().stream().findFirst().get();
133+
testData.ensureEntityAndReturnObjectsToStore(foundPerson);
134+
Assertions.assertEquals(2, testData.getEntitiesById().size());
135+
Assertions.assertEquals(2, testData.getEntities().size());
136+
}
137+
138+
@Test
139+
void idGetterFirstNullThenReturningIdDifferentObject()
140+
{
141+
final EntityData<Person, String> testData = new EntityData<>();
142+
testData.setIdGetter(null);
143+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
144+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
145+
Assertions.assertTrue(testData.getEntitiesById().isEmpty());
146+
Assertions.assertEquals(2, testData.getEntities().size());
147+
148+
testData.setIdGetter(this.idGetter);
149+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
150+
Assertions.assertEquals(2, testData.getEntitiesById().size());
151+
Assertions.assertEquals(3, testData.getEntities().size());
152+
}
153+
154+
@Test
155+
void idGetterFirstReturnNullThenReturningIdDifferentObject()
156+
{
157+
final EntityData<Person, String> testData = new EntityData<>();
158+
testData.setIdGetter(this.idNullGetter);
159+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
160+
testData.ensureEntityAndReturnObjectsToStore(new Person("2", TestData.FIRST_NAME_ALTERNATIVE));
161+
Assertions.assertEquals(1, testData.getEntitiesById().size());
162+
Assertions.assertEquals(2, testData.getEntities().size());
163+
164+
testData.setIdGetter(this.idGetter);
165+
testData.ensureEntityAndReturnObjectsToStore(new Person("1", TestData.FIRST_NAME));
166+
Assertions.assertEquals(2, testData.getEntitiesById().size());
167+
Assertions.assertEquals(3, testData.getEntities().size());
168+
}
169+
}

0 commit comments

Comments
 (0)