2828import java .util .stream .Stream ;
2929import java .util .stream .StreamSupport ;
3030
31+ import org .springframework .beans .BeansException ;
3132import org .springframework .context .ApplicationContext ;
33+ import org .springframework .context .ApplicationContextAware ;
3234import org .springframework .context .ApplicationEventPublisher ;
3335import org .springframework .data .domain .Page ;
3436import org .springframework .data .domain .Pageable ;
7072 * @author Diego Krupitza
7173 * @author Sergey Korotaev
7274 * @author Mikhail Polivakha
73- * @author Tomohiko Ozawa
7475 */
75- public class JdbcAggregateTemplate implements JdbcAggregateOperations {
76+ public class JdbcAggregateTemplate implements JdbcAggregateOperations , ApplicationContextAware {
7677
7778 private final EntityLifecycleEventDelegate eventDelegate = new EntityLifecycleEventDelegate ();
7879 private final RelationalMappingContext context ;
79-
8080 private final RelationalEntityDeleteWriter jdbcEntityDeleteWriter ;
81-
8281 private final DataAccessStrategy accessStrategy ;
8382 private final AggregateChangeExecutor executor ;
8483 private final JdbcConverter converter ;
8584
86- private EntityCallbacks entityCallbacks = EntityCallbacks . create () ;
85+ private @ Nullable EntityCallbacks entityCallbacks ;
8786
8887 /**
89- * Creates a new {@link JdbcAggregateTemplate} given {@link ApplicationContext}, {@link RelationalMappingContext} and
90- * {@link DataAccessStrategy}.
88+ * Creates a new {@link JdbcAggregateTemplate} given {@link RelationalMappingContext} and {@link DataAccessStrategy}.
9189 *
92- * @param publisher must not be {@literal null}.
90+ * @param converter must not be {@literal null}.
9391 * @param dataAccessStrategy must not be {@literal null}.
94- * @since 3.3
95- */
96- public JdbcAggregateTemplate (ApplicationContext publisher , JdbcConverter converter ,
97- DataAccessStrategy dataAccessStrategy ) {
98-
99- Assert .notNull (publisher , "ApplicationContext must not be null" );
100- Assert .notNull (converter , "RelationalConverter must not be null" );
101- Assert .notNull (dataAccessStrategy , "DataAccessStrategy must not be null" );
102-
103- this .eventDelegate .setPublisher (publisher );
104- this .converter = converter ;
105- this .accessStrategy = dataAccessStrategy ;
106- this .context = converter .getMappingContext ();
107-
108- this .jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter (context );
109-
110- this .executor = new AggregateChangeExecutor (converter , accessStrategy );
111-
112- setEntityCallbacks (EntityCallbacks .create (publisher ));
113- }
114-
115- /**
116- * Creates a new {@link JdbcAggregateTemplate} given {@link ApplicationEventPublisher},
117- * {@link RelationalMappingContext} and {@link DataAccessStrategy}.
118- *
119- * @param publisher must not be {@literal null}.
120- * @param dataAccessStrategy must not be {@literal null}.
121- * @since 3.3
92+ * @since 1.1
12293 */
123- public JdbcAggregateTemplate (ApplicationEventPublisher publisher , JdbcConverter converter ,
124- DataAccessStrategy dataAccessStrategy ) {
125-
126- Assert .notNull (publisher , "ApplicationEventPublisher must not be null" );
127- Assert .notNull (converter , "RelationalConverter must not be null" );
128- Assert .notNull (dataAccessStrategy , "DataAccessStrategy must not be null" );
129-
130- this .eventDelegate .setPublisher (publisher );
131- this .converter = converter ;
132- this .accessStrategy = dataAccessStrategy ;
133- this .context = converter .getMappingContext ();
134-
135- this .jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter (context );
136- this .executor = new AggregateChangeExecutor (converter , accessStrategy );
94+ public JdbcAggregateTemplate (JdbcConverter converter , DataAccessStrategy dataAccessStrategy ) {
95+ this (converter , converter .getMappingContext (), dataAccessStrategy );
13796 }
13897
13998 /**
14099 * Creates a new {@link JdbcAggregateTemplate} given {@link ApplicationContext}, {@link RelationalMappingContext} and
141100 * {@link DataAccessStrategy}.
142101 *
143- * @param publisher must not be {@literal null}.
102+ * @param applicationContext must not be {@literal null}.
144103 * @param context must not be {@literal null}.
104+ * @param converter must not be {@literal null}.
145105 * @param dataAccessStrategy must not be {@literal null}.
146106 * @since 1.1
147- * @deprecated since 3.3, use {@link JdbcAggregateTemplate(ApplicationContext, JdbcConverter, DataAccessStrategy)}
148- * instead.
149107 */
150- @ Deprecated (since = "3.3" )
151- public JdbcAggregateTemplate (ApplicationContext publisher , RelationalMappingContext context , JdbcConverter converter ,
152- DataAccessStrategy dataAccessStrategy ) {
153-
154- Assert .notNull (publisher , "ApplicationContext must not be null" );
155- Assert .notNull (context , "RelationalMappingContext must not be null" );
156- Assert .notNull (converter , "RelationalConverter must not be null" );
157- Assert .notNull (dataAccessStrategy , "DataAccessStrategy must not be null" );
158-
159- this .eventDelegate .setPublisher (publisher );
160- this .context = context ;
161- this .accessStrategy = dataAccessStrategy ;
162- this .converter = converter ;
163-
164- this .jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter (context );
165-
166- this .executor = new AggregateChangeExecutor (converter , accessStrategy );
167-
168- setEntityCallbacks (EntityCallbacks .create (publisher ));
108+ public JdbcAggregateTemplate (ApplicationContext applicationContext , RelationalMappingContext context ,
109+ JdbcConverter converter , DataAccessStrategy dataAccessStrategy ) {
110+ this (converter , context , dataAccessStrategy );
111+ setApplicationContext (applicationContext );
169112 }
170113
171114 /**
172115 * Creates a new {@link JdbcAggregateTemplate} given {@link ApplicationEventPublisher},
173- * {@link RelationalMappingContext} and {@link DataAccessStrategy}.
116+ * {@link RelationalMappingContext}, {@link JdbcConverter} and {@link DataAccessStrategy}.
174117 *
175118 * @param publisher must not be {@literal null}.
176119 * @param context must not be {@literal null}.
120+ * @param converter must not be {@literal null}.
177121 * @param dataAccessStrategy must not be {@literal null}.
178- * @deprecated since 3.3, use {@link JdbcAggregateTemplate(ApplicationEventPublisher, JdbcConverter,
179- * DataAccessStrategy)} instead.
180122 */
181- @ Deprecated (since = "3.3" )
182123 public JdbcAggregateTemplate (ApplicationEventPublisher publisher , RelationalMappingContext context ,
183124 JdbcConverter converter , DataAccessStrategy dataAccessStrategy ) {
184125
126+ this (converter , context , dataAccessStrategy );
127+
185128 Assert .notNull (publisher , "ApplicationEventPublisher must not be null" );
186- Assert .notNull (context , "RelationalMappingContext must not be null" );
129+
130+ if (publisher instanceof ApplicationContext applicationContext ) {
131+ setApplicationContext (applicationContext );
132+ } else {
133+ this .eventDelegate .setPublisher (publisher );
134+ }
135+ }
136+
137+ private JdbcAggregateTemplate (JdbcConverter converter , RelationalMappingContext context ,
138+ DataAccessStrategy dataAccessStrategy ) {
139+
187140 Assert .notNull (converter , "RelationalConverter must not be null" );
141+ Assert .notNull (context , "RelationalMappingContext must not be null" );
188142 Assert .notNull (dataAccessStrategy , "DataAccessStrategy must not be null" );
189143
190- this .eventDelegate .setPublisher (publisher );
191- this .context = context ;
192144 this .accessStrategy = dataAccessStrategy ;
193145 this .converter = converter ;
146+ this .context = context ;
194147
195148 this .jdbcEntityDeleteWriter = new RelationalEntityDeleteWriter (context );
196149 this .executor = new AggregateChangeExecutor (converter , accessStrategy );
197150 }
198151
152+ @ Override
153+ public void setApplicationContext (ApplicationContext applicationContext ) throws BeansException {
154+
155+ Assert .notNull (applicationContext , "ApplicationContext must not be null" );
156+
157+ if (entityCallbacks == null ) {
158+ setEntityCallbacks (EntityCallbacks .create (applicationContext ));
159+ }
160+
161+ this .eventDelegate .setPublisher (applicationContext );
162+ }
163+
199164 /**
200165 * Sets the callbacks to be invoked on life cycle events.
201166 *
@@ -519,6 +484,16 @@ public <T> void deleteAll(Iterable<? extends T> instances) {
519484 }
520485 }
521486
487+ @ Override
488+ public DataAccessStrategy getDataAccessStrategy () {
489+ return accessStrategy ;
490+ }
491+
492+ @ Override
493+ public JdbcConverter getConverter () {
494+ return converter ;
495+ }
496+
522497 private <T > void verifyIdProperty (T instance ) {
523498 // accessing the id property just to raise an exception in the case it does not exist.
524499 context .getRequiredPersistentEntity (instance .getClass ()).getRequiredIdProperty ();
@@ -711,33 +686,35 @@ private <T> List<T> triggerAfterConvert(Iterable<T> all) {
711686 private <T > T triggerAfterConvert (T entity ) {
712687
713688 eventDelegate .publishEvent (() -> new AfterConvertEvent <>(entity ));
714- return entityCallbacks .callback (AfterConvertCallback .class , entity );
689+ return entityCallbacks != null ? entityCallbacks .callback (AfterConvertCallback .class , entity ) : entity ;
715690 }
716691
717692 private <T > T triggerBeforeConvert (T aggregateRoot ) {
718693
719694 eventDelegate .publishEvent (() -> new BeforeConvertEvent <>(aggregateRoot ));
720- return entityCallbacks .callback (BeforeConvertCallback .class , aggregateRoot );
695+ return entityCallbacks != null ? entityCallbacks .callback (BeforeConvertCallback .class , aggregateRoot )
696+ : aggregateRoot ;
721697 }
722698
723699 private <T > T triggerBeforeSave (T aggregateRoot , AggregateChange <T > change ) {
724700
725701 eventDelegate .publishEvent (() -> new BeforeSaveEvent <>(aggregateRoot , change ));
726702
727- return entityCallbacks .callback (BeforeSaveCallback .class , aggregateRoot , change );
703+ return entityCallbacks != null ? entityCallbacks .callback (BeforeSaveCallback .class , aggregateRoot , change )
704+ : aggregateRoot ;
728705 }
729706
730707 private <T > T triggerAfterSave (T aggregateRoot , AggregateChange <T > change ) {
731708
732709 eventDelegate .publishEvent (() -> new AfterSaveEvent <>(aggregateRoot , change ));
733- return entityCallbacks .callback (AfterSaveCallback .class , aggregateRoot );
710+ return entityCallbacks != null ? entityCallbacks .callback (AfterSaveCallback .class , aggregateRoot ) : aggregateRoot ;
734711 }
735712
736713 private <T > void triggerAfterDelete (@ Nullable T aggregateRoot , Object id , AggregateChange <T > change ) {
737714
738715 eventDelegate .publishEvent (() -> new AfterDeleteEvent <>(Identifier .of (id ), aggregateRoot , change ));
739716
740- if (aggregateRoot != null ) {
717+ if (aggregateRoot != null && entityCallbacks != null ) {
741718 entityCallbacks .callback (AfterDeleteCallback .class , aggregateRoot );
742719 }
743720 }
@@ -747,11 +724,11 @@ private <T> T triggerBeforeDelete(@Nullable T aggregateRoot, Object id, MutableA
747724
748725 eventDelegate .publishEvent (() -> new BeforeDeleteEvent <>(Identifier .of (id ), aggregateRoot , change ));
749726
750- if (aggregateRoot != null ) {
727+ if (aggregateRoot != null && entityCallbacks != null ) {
751728 return entityCallbacks .callback (BeforeDeleteCallback .class , aggregateRoot , change );
752729 }
753730
754- return null ;
731+ return aggregateRoot ;
755732 }
756733
757734 private record EntityAndPreviousVersion <T >(T entity , @ Nullable Number version ) {
@@ -764,13 +741,4 @@ private interface AggregateChangeCreator<T> {
764741 RootAggregateChange <T > createAggregateChange (T instance );
765742 }
766743
767- @ Override
768- public DataAccessStrategy getDataAccessStrategy () {
769- return accessStrategy ;
770- }
771-
772- @ Override
773- public JdbcConverter getConverter () {
774- return converter ;
775- }
776744}
0 commit comments