1515 */
1616package org .springframework .data .neo4j .core ;
1717
18- import java .util .Collection ;
19- import java .util .Collections ;
20- import java .util .List ;
21- import java .util .Map ;
22-
2318import org .apiguardian .api .API ;
2419import org .springframework .core .CollectionFactory ;
2520import org .springframework .data .mapping .PersistentPropertyAccessor ;
2621import org .springframework .data .neo4j .core .mapping .Neo4jPersistentProperty ;
2722
23+ import java .util .Collection ;
24+ import java .util .Collections ;
25+ import java .util .Map ;
26+ import java .util .Optional ;
27+
2828/**
2929 * Internal helper class that takes care of tracking whether a related object or a collection of related objects was recreated
3030 * due to changing immutable properties
@@ -45,19 +45,19 @@ enum Cardinality {
4545 static RelationshipHandler forProperty (Neo4jPersistentProperty property , Object rawValue ) {
4646
4747 Cardinality cardinality ;
48- Collection <Object > newRelationshipObjectCollection = null ;
49- Map <Object , Object > newRelationshipObjectCollectionMap = null ;
48+ Collection <Object > newRelationshipObjectCollection = Collections . emptyList () ;
49+ Map <Object , Object > newRelationshipObjectCollectionMap = Collections . emptyMap () ;
5050
5151 // Order is important here, all map based associations are dynamic, but not all dynamic associations are one to many
5252 if (property .isCollectionLike ()) {
5353 cardinality = Cardinality .ONE_TO_MANY ;
54- newRelationshipObjectCollection = CollectionFactory .createApproximateCollection ( rawValue , ((Collection <?>) rawValue ).size ());
54+ newRelationshipObjectCollection = CollectionFactory .createCollection ( property . getType () , ((Collection <?>) rawValue ).size ());
5555 } else if (property .isDynamicOneToManyAssociation ()) {
5656 cardinality = Cardinality .DYNAMIC_ONE_TO_MANY ;
57- newRelationshipObjectCollectionMap = CollectionFactory .createApproximateMap ( rawValue , ((Map <?, ?>) rawValue ).size ());
57+ newRelationshipObjectCollectionMap = CollectionFactory .createMap ( property . getType () , ((Map <?, ?>) rawValue ).size ());
5858 } else if (property .isDynamicAssociation ()) {
5959 cardinality = Cardinality .DYNAMIC_ONE_TO_ONE ;
60- newRelationshipObjectCollectionMap = CollectionFactory .createApproximateMap ( rawValue , ((Map <?, ?>) rawValue ).size ());
60+ newRelationshipObjectCollectionMap = CollectionFactory .createMap ( property . getType () , ((Map <?, ?>) rawValue ).size ());
6161 } else {
6262 cardinality = Cardinality .ONE_TO_ONE ;
6363 }
@@ -76,9 +76,9 @@ static RelationshipHandler forProperty(Neo4jPersistentProperty property, Object
7676 private final Map <Object , Object > newRelatedObjectsByType ;
7777
7878 RelationshipHandler (Neo4jPersistentProperty property ,
79- Object rawValue , Cardinality cardinality ,
80- Collection <Object > newRelatedObjects ,
81- Map <Object , Object > newRelatedObjectsByType ) {
79+ Object rawValue , Cardinality cardinality ,
80+ Collection <Object > newRelatedObjects ,
81+ Map <Object , Object > newRelatedObjectsByType ) {
8282 this .property = property ;
8383 this .rawValue = rawValue ;
8484 this .cardinality = cardinality ;
@@ -87,31 +87,33 @@ static RelationshipHandler forProperty(Neo4jPersistentProperty property, Object
8787 }
8888
8989 void handle (Object relatedValueToStore , Object newRelatedObject , Object potentiallyRecreatedRelatedObject ) {
90- if (potentiallyRecreatedRelatedObject == newRelatedObject ) {
91- return ;
92- } else if (cardinality == Cardinality .ONE_TO_ONE ) {
93- this .newRelatedObjects = Collections .singletonList (potentiallyRecreatedRelatedObject );
94- } else if (cardinality == Cardinality .ONE_TO_MANY ) {
95- newRelatedObjects .add (potentiallyRecreatedRelatedObject );
96- } else {
97- Object key = ((Map .Entry <Object , Object >) relatedValueToStore ).getKey ();
98- if (cardinality == Cardinality .DYNAMIC_ONE_TO_ONE ) {
99- newRelatedObjectsByType .put (key , potentiallyRecreatedRelatedObject );
90+
91+ if (potentiallyRecreatedRelatedObject != newRelatedObject ) {
92+ if (cardinality == Cardinality .ONE_TO_ONE ) {
93+ this .newRelatedObjects = Collections .singletonList (potentiallyRecreatedRelatedObject );
94+ } else if (cardinality == Cardinality .ONE_TO_MANY ) {
95+ newRelatedObjects .add (potentiallyRecreatedRelatedObject );
10096 } else {
101- Collection <Object > newCollection = (Collection <Object >) newRelatedObjectsByType
102- .computeIfAbsent (key , k -> CollectionFactory .createCollection (
103- property .getTypeInformation ().getRequiredActualType ().getType (),
104- ((Collection ) ((Map ) rawValue ).get (key )).size ()));
105- newCollection .add (potentiallyRecreatedRelatedObject );
97+ Object key = ((Map .Entry <Object , Object >) relatedValueToStore ).getKey ();
98+ if (cardinality == Cardinality .DYNAMIC_ONE_TO_ONE ) {
99+ newRelatedObjectsByType .put (key , potentiallyRecreatedRelatedObject );
100+ } else {
101+ Collection <Object > newCollection = (Collection <Object >) newRelatedObjectsByType
102+ .computeIfAbsent (key , k -> CollectionFactory .createCollection (
103+ property .getTypeInformation ().getRequiredActualType ().getType (),
104+ ((Collection ) ((Map ) rawValue ).get (key )).size ()));
105+ newCollection .add (potentiallyRecreatedRelatedObject );
106+ }
106107 }
107108 }
108109 }
109110
110111 void applyFinalResultToOwner (PersistentPropertyAccessor <?> parentPropertyAccessor ) {
112+
111113 Object finalRelation = null ;
112114 switch (cardinality ) {
113115 case ONE_TO_ONE :
114- finalRelation = newRelatedObjects == null ? null : (( List ) newRelatedObjects ). get ( 0 );
116+ finalRelation = Optional . ofNullable ( newRelatedObjects ). flatMap ( v -> v . stream (). findFirst ()). orElse ( null );
115117 break ;
116118 case ONE_TO_MANY :
117119 if (!newRelatedObjects .isEmpty ()) {
0 commit comments