3535import org .springframework .data .relational .core .conversion .RelationalEntityDeleteWriter ;
3636import org .springframework .data .relational .core .conversion .RelationalEntityInsertWriter ;
3737import org .springframework .data .relational .core .conversion .RelationalEntityUpdateWriter ;
38+ import org .springframework .data .relational .core .conversion .RelationalEntityVersionUtils ;
3839import org .springframework .data .relational .core .mapping .RelationalMappingContext ;
3940import org .springframework .data .relational .core .mapping .RelationalPersistentEntity ;
41+ import org .springframework .data .relational .core .mapping .RelationalPersistentProperty ;
4042import org .springframework .data .relational .core .mapping .event .*;
4143import org .springframework .data .support .PageableExecutionUtils ;
4244import org .springframework .lang .Nullable ;
@@ -63,6 +65,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
6365
6466 private final DataAccessStrategy accessStrategy ;
6567 private final AggregateChangeExecutor executor ;
68+ private final JdbcConverter converter ;
6669
6770 private EntityCallbacks entityCallbacks = EntityCallbacks .create ();
6871
@@ -86,6 +89,7 @@ public JdbcAggregateTemplate(ApplicationContext publisher, RelationalMappingCont
8689 this .publisher = publisher ;
8790 this .context = context ;
8891 this .accessStrategy = dataAccessStrategy ;
92+ this .converter = converter ;
8993
9094 this .jdbcEntityInsertWriter = new RelationalEntityInsertWriter (context );
9195 this .jdbcEntityUpdateWriter = new RelationalEntityUpdateWriter (context );
@@ -115,6 +119,7 @@ public JdbcAggregateTemplate(ApplicationEventPublisher publisher, RelationalMapp
115119 this .publisher = publisher ;
116120 this .context = context ;
117121 this .accessStrategy = dataAccessStrategy ;
122+ this .converter = converter ;
118123
119124 this .jdbcEntityInsertWriter = new RelationalEntityInsertWriter (context );
120125 this .jdbcEntityUpdateWriter = new RelationalEntityUpdateWriter (context );
@@ -332,7 +337,7 @@ private <T> T store(T aggregateRoot, Function<T, MutableAggregateChange<T>> chan
332337
333338 MutableAggregateChange <T > change = changeCreator .apply (aggregateRoot );
334339
335- aggregateRoot = triggerBeforeSave (aggregateRoot , change );
340+ aggregateRoot = triggerBeforeSave (change . getEntity () , change );
336341
337342 change .setEntity (aggregateRoot );
338343
@@ -359,21 +364,58 @@ private <T> void deleteTree(Object id, @Nullable T entity, Class<T> domainType)
359364
360365 private <T > MutableAggregateChange <T > createInsertChange (T instance ) {
361366
362- MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forSave (instance );
363- jdbcEntityInsertWriter .write (instance , aggregateChange );
367+ RelationalPersistentEntity <T > persistentEntity = getRequiredPersistentEntity (instance );
368+ T preparedInstance = instance ;
369+ if (persistentEntity .hasVersionProperty ()) {
370+ RelationalPersistentProperty versionProperty = persistentEntity .getRequiredVersionProperty ();
371+
372+ long initialVersion = versionProperty .getActualType ().isPrimitive () ? 1L : 0 ;
373+
374+ preparedInstance = RelationalEntityVersionUtils .setVersionNumberOnEntity ( //
375+ instance , initialVersion , persistentEntity , converter );
376+ }
377+ MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forSave (preparedInstance );
378+ jdbcEntityInsertWriter .write (preparedInstance , aggregateChange );
364379 return aggregateChange ;
365380 }
366381
367382 private <T > MutableAggregateChange <T > createUpdateChange (T instance ) {
368383
369- MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forSave (instance );
370- jdbcEntityUpdateWriter .write (instance , aggregateChange );
384+ RelationalPersistentEntity <T > persistentEntity = getRequiredPersistentEntity (instance );
385+ T preparedInstance = instance ;
386+ Number previousVersion = null ;
387+ if (persistentEntity .hasVersionProperty ()) {
388+ // If the root aggregate has a version property, increment it.
389+ previousVersion = RelationalEntityVersionUtils .getVersionNumberFromEntity (instance ,
390+ persistentEntity , converter );
391+
392+ Assert .notNull (previousVersion , "The root aggregate cannot be updated because the version property is null." );
393+
394+ long newVersion = previousVersion .longValue () + 1 ;
395+
396+ preparedInstance = RelationalEntityVersionUtils .setVersionNumberOnEntity (instance , newVersion ,
397+ persistentEntity , converter );
398+ }
399+ MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forSave (preparedInstance , previousVersion );
400+ jdbcEntityUpdateWriter .write (preparedInstance , aggregateChange );
371401 return aggregateChange ;
372402 }
373403
404+ @ SuppressWarnings ("unchecked" )
405+ private <T > RelationalPersistentEntity <T > getRequiredPersistentEntity (T instance ) {
406+ return (RelationalPersistentEntity <T >) context .getRequiredPersistentEntity (instance .getClass ());
407+ }
408+
374409 private <T > MutableAggregateChange <T > createDeletingChange (Object id , @ Nullable T entity , Class <T > domainType ) {
375410
376- MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forDelete (domainType , entity );
411+ Number previousVersion = null ;
412+ if (entity != null ) {
413+ RelationalPersistentEntity <T > persistentEntity = getRequiredPersistentEntity (entity );
414+ if (persistentEntity .hasVersionProperty ()) {
415+ previousVersion = RelationalEntityVersionUtils .getVersionNumberFromEntity (entity , persistentEntity , converter );
416+ }
417+ }
418+ MutableAggregateChange <T > aggregateChange = MutableAggregateChange .forDelete (domainType , entity , previousVersion );
377419 jdbcEntityDeleteWriter .write (id , aggregateChange );
378420 return aggregateChange ;
379421 }
0 commit comments