17
17
18
18
import java .util .*;
19
19
import java .util .function .BiConsumer ;
20
+ import java .util .function .Function ;
20
21
import java .util .stream .Collectors ;
21
22
22
23
import org .springframework .dao .IncorrectUpdateSemanticsDataAccessException ;
@@ -72,19 +73,16 @@ class JdbcAggregateChangeExecutionContext {
72
73
73
74
<T > void executeInsertRoot (DbAction .InsertRoot <T > insert ) {
74
75
75
- Object id = accessStrategy .insert (insert .getEntity (), insert .getEntityType (), Identifier .empty (),
76
- insert .getIdValueSource ());
76
+ Object id = accessStrategy .insert (insert .getEntity (), insert .getEntityType (), Identifier .empty (), insert .getIdValueSource ());
77
77
add (new DbActionExecutionResult (insert , id ));
78
78
}
79
79
80
80
<T > void executeBatchInsertRoot (DbAction .BatchInsertRoot <T > batchInsertRoot ) {
81
81
82
82
List <DbAction .InsertRoot <T >> inserts = batchInsertRoot .getActions ();
83
- List <InsertSubject <T >> insertSubjects = inserts .stream ()
84
- .map (insert -> InsertSubject .describedBy (insert .getEntity (), Identifier .empty ())).collect (Collectors .toList ());
83
+ List <InsertSubject <T >> insertSubjects = inserts .stream ().map (insert -> InsertSubject .describedBy (insert .getEntity (), Identifier .empty ())).collect (Collectors .toList ());
85
84
86
- Object [] ids = accessStrategy .insert (insertSubjects , batchInsertRoot .getEntityType (),
87
- batchInsertRoot .getBatchValue ());
85
+ Object [] ids = accessStrategy .insert (insertSubjects , batchInsertRoot .getEntityType (), batchInsertRoot .getBatchValue ());
88
86
89
87
for (int i = 0 ; i < inserts .size (); i ++) {
90
88
add (new DbActionExecutionResult (inserts .get (i ), ids .length > 0 ? ids [i ] : null ));
@@ -94,17 +92,14 @@ <T> void executeBatchInsertRoot(DbAction.BatchInsertRoot<T> batchInsertRoot) {
94
92
<T > void executeInsert (DbAction .Insert <T > insert ) {
95
93
96
94
Identifier parentKeys = getParentKeys (insert , converter );
97
- Object id = accessStrategy .insert (insert .getEntity (), insert .getEntityType (), parentKeys ,
98
- insert .getIdValueSource ());
95
+ Object id = accessStrategy .insert (insert .getEntity (), insert .getEntityType (), parentKeys , insert .getIdValueSource ());
99
96
add (new DbActionExecutionResult (insert , id ));
100
97
}
101
98
102
99
<T > void executeBatchInsert (DbAction .BatchInsert <T > batchInsert ) {
103
100
104
101
List <DbAction .Insert <T >> inserts = batchInsert .getActions ();
105
- List <InsertSubject <T >> insertSubjects = inserts .stream ()
106
- .map (insert -> InsertSubject .describedBy (insert .getEntity (), getParentKeys (insert , converter )))
107
- .collect (Collectors .toList ());
102
+ List <InsertSubject <T >> insertSubjects = inserts .stream ().map (insert -> InsertSubject .describedBy (insert .getEntity (), getParentKeys (insert , converter ))).collect (Collectors .toList ());
108
103
109
104
Object [] ids = accessStrategy .insert (insertSubjects , batchInsert .getEntityType (), batchInsert .getBatchValue ());
110
105
@@ -176,20 +171,34 @@ private Identifier getParentKeys(DbAction.WithDependingOn<?> action, JdbcConvert
176
171
Object id = getParentId (action );
177
172
178
173
JdbcIdentifierBuilder identifier = JdbcIdentifierBuilder //
179
- .forBackReferences (converter , context .getAggregatePath (action .getPropertyPath ()), id );
174
+ .forBackReferences (converter , context .getAggregatePath (action .getPropertyPath ()),
175
+ getValueProvider (id , context .getAggregatePath (action .getPropertyPath ()), converter ));
180
176
181
- for (Map .Entry <PersistentPropertyPath <RelationalPersistentProperty >, Object > qualifier : action .getQualifiers ()
182
- .entrySet ()) {
177
+ for (Map .Entry <PersistentPropertyPath <RelationalPersistentProperty >, Object > qualifier : action .getQualifiers ().entrySet ()) {
183
178
identifier = identifier .withQualifier (context .getAggregatePath (qualifier .getKey ()), qualifier .getValue ());
184
179
}
185
180
186
181
return identifier .build ();
187
182
}
188
183
184
+ static Function <AggregatePath , Object > getValueProvider (Object idValue , AggregatePath path , JdbcConverter converter ) {
185
+
186
+ RelationalPersistentEntity <?> entity = converter .getMappingContext ().getPersistentEntity (path .getIdDefiningParentPath ().getRequiredIdProperty ().getType ());
187
+
188
+ Function <AggregatePath , Object > valueProvider = ap -> {
189
+ if (entity == null ) {
190
+ return idValue ;
191
+ } else {
192
+ PersistentPropertyPathAccessor <Object > propertyPathAccessor = entity .getPropertyPathAccessor (idValue );
193
+ return propertyPathAccessor .getProperty (ap .getRequiredPersistentPropertyPath ());
194
+ }
195
+ };
196
+ return valueProvider ;
197
+ }
198
+
189
199
private Object getParentId (DbAction .WithDependingOn <?> action ) {
190
200
191
- DbAction .WithEntity <?> idOwningAction = getIdOwningAction (action ,
192
- context .getAggregatePath (action .getPropertyPath ()).getIdDefiningParentPath ());
201
+ DbAction .WithEntity <?> idOwningAction = getIdOwningAction (action , context .getAggregatePath (action .getPropertyPath ()).getIdDefiningParentPath ());
193
202
194
203
return getPotentialGeneratedIdFrom (idOwningAction );
195
204
}
@@ -198,8 +207,7 @@ private DbAction.WithEntity<?> getIdOwningAction(DbAction.WithEntity<?> action,
198
207
199
208
if (!(action instanceof DbAction .WithDependingOn <?> withDependingOn )) {
200
209
201
- Assert .state (idPath .isRoot (),
202
- "When the id path is not empty the id providing action should be of type WithDependingOn" );
210
+ Assert .state (idPath .isRoot (), "When the id path is not empty the id providing action should be of type WithDependingOn" );
203
211
204
212
return action ;
205
213
}
@@ -267,20 +275,16 @@ <T> List<T> populateIdsIfNecessary() {
267
275
268
276
if (newEntity != action .getEntity ()) {
269
277
270
- cascadingValues .stage (insert .getDependingOn (), insert .getPropertyPath (),
271
- qualifierValue , newEntity );
278
+ cascadingValues .stage (insert .getDependingOn (), insert .getPropertyPath (), qualifierValue , newEntity );
272
279
} else if (insert .getPropertyPath ().getLeafProperty ().isCollectionLike ()) {
273
280
274
- cascadingValues .gather (insert .getDependingOn (), insert .getPropertyPath (),
275
- qualifierValue , newEntity );
281
+ cascadingValues .gather (insert .getDependingOn (), insert .getPropertyPath (), qualifierValue , newEntity );
276
282
}
277
283
}
278
284
}
279
285
280
286
if (roots .isEmpty ()) {
281
- throw new IllegalStateException (
282
- String .format ("Cannot retrieve the resulting instance(s) unless a %s or %s action was successfully executed" ,
283
- DbAction .InsertRoot .class .getName (), DbAction .UpdateRoot .class .getName ()));
287
+ throw new IllegalStateException (String .format ("Cannot retrieve the resulting instance(s) unless a %s or %s action was successfully executed" , DbAction .InsertRoot .class .getName (), DbAction .UpdateRoot .class .getName ()));
284
288
}
285
289
286
290
Collections .reverse (roots );
@@ -289,23 +293,19 @@ <T> List<T> populateIdsIfNecessary() {
289
293
}
290
294
291
295
@ SuppressWarnings ("unchecked" )
292
- private <S > Object setIdAndCascadingProperties (DbAction .WithEntity <S > action , @ Nullable Object generatedId ,
293
- StagedValues cascadingValues ) {
296
+ private <S > Object setIdAndCascadingProperties (DbAction .WithEntity <S > action , @ Nullable Object generatedId , StagedValues cascadingValues ) {
294
297
295
298
S originalEntity = action .getEntity ();
296
299
297
- RelationalPersistentEntity <S > persistentEntity = (RelationalPersistentEntity <S >) context
298
- .getRequiredPersistentEntity (action .getEntityType ());
299
- PersistentPropertyPathAccessor <S > propertyAccessor = converter .getPropertyAccessor (persistentEntity ,
300
- originalEntity );
300
+ RelationalPersistentEntity <S > persistentEntity = (RelationalPersistentEntity <S >) context .getRequiredPersistentEntity (action .getEntityType ());
301
+ PersistentPropertyPathAccessor <S > propertyAccessor = converter .getPropertyAccessor (persistentEntity , originalEntity );
301
302
302
303
if (IdValueSource .GENERATED .equals (action .getIdValueSource ())) {
303
304
propertyAccessor .setProperty (persistentEntity .getRequiredIdProperty (), generatedId );
304
305
}
305
306
306
307
// set values of changed immutables referenced by this entity
307
- cascadingValues .forEachPath (action , (persistentPropertyPath , o ) -> propertyAccessor
308
- .setProperty (getRelativePath (action , persistentPropertyPath ), o ));
308
+ cascadingValues .forEachPath (action , (persistentPropertyPath , o ) -> propertyAccessor .setProperty (getRelativePath (action , persistentPropertyPath ), o ));
309
309
310
310
return propertyAccessor .getBean ();
311
311
}
@@ -337,8 +337,7 @@ private <T> void updateWithoutVersion(DbAction.UpdateRoot<T> update) {
337
337
338
338
if (!accessStrategy .update (update .getEntity (), update .getEntityType ())) {
339
339
340
- throw new IncorrectUpdateSemanticsDataAccessException (
341
- String .format (UPDATE_FAILED , update .getEntity (), getIdFrom (update )));
340
+ throw new IncorrectUpdateSemanticsDataAccessException (String .format (UPDATE_FAILED , update .getEntity (), getIdFrom (update )));
342
341
}
343
342
}
344
343
@@ -359,21 +358,20 @@ private <T> void updateWithVersion(DbAction.UpdateRoot<T> update) {
359
358
*/
360
359
private static class StagedValues {
361
360
362
- static final List <MultiValueAggregator <?>> aggregators = Arrays .asList (SetAggregator .INSTANCE , MapAggregator .INSTANCE ,
363
- ListAggregator .INSTANCE , SingleElementAggregator .INSTANCE );
361
+ static final List <MultiValueAggregator <?>> aggregators = Arrays .asList (SetAggregator .INSTANCE , MapAggregator .INSTANCE , ListAggregator .INSTANCE , SingleElementAggregator .INSTANCE );
364
362
365
363
Map <DbAction , Map <PersistentPropertyPath , StagedValue >> values = new HashMap <>();
366
364
367
365
/**
368
366
* Adds a value that needs to be set in an entity higher up in the tree of entities in the aggregate. If the
369
367
* attribute to be set is multivalued this method expects only a single element.
370
368
*
371
- * @param action The action responsible for persisting the entity that needs the added value set. Must not be
372
- * {@literal null}.
373
- * @param path The path to the property in which to set the value. Must not be {@literal null}.
369
+ * @param action The action responsible for persisting the entity that needs the added value set. Must not be
370
+ * {@literal null}.
371
+ * @param path The path to the property in which to set the value. Must not be {@literal null}.
374
372
* @param qualifier If {@code path} is a qualified multivalued properties this parameter contains the qualifier. May
375
- * be {@literal null}.
376
- * @param value The value to be set. Must not be {@literal null}.
373
+ * be {@literal null}.
374
+ * @param value The value to be set. Must not be {@literal null}.
377
375
*/
378
376
void stage (DbAction <?> action , PersistentPropertyPath path , @ Nullable Object qualifier , Object value ) {
379
377
@@ -386,11 +384,9 @@ <T> StagedValue gather(DbAction<?> action, PersistentPropertyPath path, @Nullabl
386
384
387
385
MultiValueAggregator <T > aggregator = getAggregatorFor (path );
388
386
389
- Map <PersistentPropertyPath , StagedValue > valuesForPath = this .values .computeIfAbsent (action ,
390
- dbAction -> new HashMap <>());
387
+ Map <PersistentPropertyPath , StagedValue > valuesForPath = this .values .computeIfAbsent (action , dbAction -> new HashMap <>());
391
388
392
- StagedValue stagedValue = valuesForPath .computeIfAbsent (path ,
393
- persistentPropertyPath -> new StagedValue (aggregator .createEmptyInstance ()));
389
+ StagedValue stagedValue = valuesForPath .computeIfAbsent (path , persistentPropertyPath -> new StagedValue (aggregator .createEmptyInstance ()));
394
390
T currentValue = (T ) stagedValue .value ;
395
391
396
392
stagedValue .value = aggregator .add (currentValue , qualifier , value );
@@ -430,7 +426,8 @@ void forEachPath(DbAction<?> dbAction, BiConsumer<PersistentPropertyPath, Object
430
426
}
431
427
432
428
private static class StagedValue {
433
- @ Nullable Object value ;
429
+ @ Nullable
430
+ Object value ;
434
431
boolean isStaged ;
435
432
436
433
public StagedValue (@ Nullable Object value ) {
0 commit comments