Skip to content

Commit 0858c04

Browse files
GH-2124 - Fix failing save for uninitialized maps of dynamic properties.
This closes #2124.
1 parent fbdc7ec commit 0858c04

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

src/main/java/org/springframework/data/neo4j/core/mapping/MappingSupport.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ public final class MappingSupport {
4646
* @return A unified collection (Either a collection of Map.Entry for dynamic and relationships with properties or a
4747
* list of related values)
4848
*/
49-
public static @Nullable Collection<?> unifyRelationshipValue(Neo4jPersistentProperty property, Object rawValue) {
49+
public static Collection<?> unifyRelationshipValue(Neo4jPersistentProperty property, @Nullable Object rawValue) {
50+
51+
if (rawValue == null) {
52+
return Collections.emptyList();
53+
}
54+
5055
Collection<?> unifiedValue;
5156
if (property.isDynamicAssociation()) {
5257
if (property.isDynamicOneToManyAssociation()) {

src/test/java/org/springframework/data/neo4j/integration/properties/DomainClasses.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import lombok.Getter;
2020
import lombok.Setter;
2121

22+
import java.util.ArrayList;
2223
import java.util.Date;
2324
import java.util.HashMap;
2425
import java.util.List;
@@ -145,4 +146,32 @@ static class WeirdSource {
145146
@Relationship(type = "ITS_COMPLICATED")
146147
IrrelevantTargetContainer irrelevantTargetContainer;
147148
}
149+
150+
@Node
151+
@Getter @Setter
152+
static class LonelySourceContainer {
153+
@Id @GeneratedValue
154+
private Long id;
155+
156+
@Relationship(type = "RELATIONSHIP_PROPERTY_CONTAINER")
157+
RelationshipPropertyContainer single;
158+
159+
@Relationship(type = "RELATIONSHIP_PROPERTY_CONTAINER_2")
160+
List<RelationshipPropertyContainer> multiNull;
161+
162+
@Relationship(type = "RELATIONSHIP_PROPERTY_CONTAINER_3")
163+
List<RelationshipPropertyContainer> multiEmpty = new ArrayList<>();
164+
165+
@Relationship
166+
Map<String, List<IrrelevantTargetContainer>> dynNullList;
167+
168+
@Relationship
169+
Map<String, List<SimpleGeneratedIDPropertyContainer>> dynEmptyList = new HashMap<>();
170+
171+
@Relationship
172+
Map<String, SimpleGeneratedIDPropertyContainerWithVersion> dynNullSingle;
173+
174+
@Relationship
175+
Map<String, SimplePropertyContainer> dynEmptySingle = new HashMap<>();
176+
}
148177
}

src/test/java/org/springframework/data/neo4j/integration/properties/PropertyIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ void customConvertersForRelsMustBeTakenIntoAccount() {
235235
}
236236
}
237237

238+
@Test // GH-2124
239+
void shouldNotFailWithEmptyOrNullRelationshipProperties() {
240+
241+
DomainClasses.LonelySourceContainer s = template.save(new DomainClasses.LonelySourceContainer());
242+
try (Session session = driver.session()) {
243+
long cnt = session.run("MATCH (m) WHERE id(m) = $id RETURN count(m)", Collections.singletonMap("id", s.getId())).single().get(0).asLong();
244+
assertThat(cnt).isEqualTo(1L);
245+
}
246+
}
247+
238248
@Configuration
239249
@EnableTransactionManagement
240250
static class Config extends AbstractNeo4jConfig {

src/test/java/org/springframework/data/neo4j/integration/properties/ReactivePropertyIT.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,22 @@ void customConvertersForRelsMustBeTakenIntoAccount() {
253253
}
254254
}
255255

256+
@Test // GH-2124
257+
void shouldNotFailWithEmptyOrNullRelationshipProperties() {
258+
259+
List<Long> recorded = new ArrayList<>();
260+
template.save(new DomainClasses.LonelySourceContainer())
261+
.map(DomainClasses.LonelySourceContainer::getId)
262+
.as(StepVerifier::create)
263+
.recordWith(() -> recorded)
264+
.expectNextCount(1L)
265+
.verifyComplete();
266+
try (Session session = driver.session()) {
267+
long cnt = session.run("MATCH (m) WHERE id(m) = $id RETURN count(m)", Collections.singletonMap("id", recorded.get(0))).single().get(0).asLong();
268+
assertThat(cnt).isEqualTo(1L);
269+
}
270+
}
271+
256272
@Configuration
257273
@EnableTransactionManagement
258274
static class Config extends AbstractReactiveNeo4jConfig {

0 commit comments

Comments
 (0)