Skip to content

Commit 3cd25ee

Browse files
schaudermp911de
authored andcommitted
Introducing AfterConvertCallback/Event.
This is to replace the AfterLoadCallback/Event in order to match the naming of other store modules. AfterLoadCallback/Event is still in place for now, but deprecated. Closes #1053 Original pull request: #1060.
1 parent b02ee3c commit 3cd25ee

File tree

12 files changed

+154
-25
lines changed

12 files changed

+154
-25
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public <T> T findById(Object id, Class<T> domainType) {
208208

209209
T entity = accessStrategy.findById(id, domainType);
210210
if (entity != null) {
211-
return triggerAfterLoad(entity);
211+
return triggerAfterConvert(entity);
212212
}
213213
return entity;
214214
}
@@ -236,7 +236,7 @@ public <T> Iterable<T> findAll(Class<T> domainType, Sort sort) {
236236
Assert.notNull(domainType, "Domain type must not be null!");
237237

238238
Iterable<T> all = accessStrategy.findAll(domainType, sort);
239-
return triggerAfterLoad(all);
239+
return triggerAfterConvert(all);
240240
}
241241

242242
/*
@@ -248,7 +248,7 @@ public <T> Page<T> findAll(Class<T> domainType, Pageable pageable) {
248248

249249
Assert.notNull(domainType, "Domain type must not be null!");
250250

251-
Iterable<T> items = triggerAfterLoad(accessStrategy.findAll(domainType, pageable));
251+
Iterable<T> items = triggerAfterConvert(accessStrategy.findAll(domainType, pageable));
252252
List<T> content = StreamSupport.stream(items.spliterator(), false).collect(Collectors.toList());
253253

254254
return PageableExecutionUtils.getPage(content, pageable, () -> accessStrategy.count(domainType));
@@ -264,7 +264,7 @@ public <T> Iterable<T> findAll(Class<T> domainType) {
264264
Assert.notNull(domainType, "Domain type must not be null!");
265265

266266
Iterable<T> all = accessStrategy.findAll(domainType);
267-
return triggerAfterLoad(all);
267+
return triggerAfterConvert(all);
268268
}
269269

270270
/*
@@ -278,7 +278,7 @@ public <T> Iterable<T> findAllById(Iterable<?> ids, Class<T> domainType) {
278278
Assert.notNull(domainType, "Domain type must not be null!");
279279

280280
Iterable<T> allById = accessStrategy.findAllById(ids, domainType);
281-
return triggerAfterLoad(allById);
281+
return triggerAfterConvert(allById);
282282
}
283283

284284
/*
@@ -385,22 +385,24 @@ private MutableAggregateChange<?> createDeletingChange(Class<?> domainType) {
385385
return aggregateChange;
386386
}
387387

388-
private <T> Iterable<T> triggerAfterLoad(Iterable<T> all) {
388+
private <T> Iterable<T> triggerAfterConvert(Iterable<T> all) {
389389

390390
List<T> result = new ArrayList<>();
391391

392392
for (T e : all) {
393-
result.add(triggerAfterLoad(e));
393+
result.add(triggerAfterConvert(e));
394394
}
395395

396396
return result;
397397
}
398398

399-
private <T> T triggerAfterLoad(T entity) {
399+
private <T> T triggerAfterConvert(T entity) {
400400

401401
publisher.publishEvent(new AfterLoadEvent<>(entity));
402+
publisher.publishEvent(new AfterConvertEvent<>(entity));
402403

403-
return entityCallbacks.callback(AfterLoadCallback.class, entity);
404+
entity = entityCallbacks.callback(AfterLoadCallback.class, entity);
405+
return entityCallbacks.callback(AfterConvertCallback.class, entity);
404406
}
405407

406408
private <T> T triggerBeforeConvert(T aggregateRoot) {

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/support/JdbcQueryLookupStrategy.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.springframework.data.relational.core.dialect.Dialect;
3333
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
3434
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
35+
import org.springframework.data.relational.core.mapping.event.AfterConvertCallback;
36+
import org.springframework.data.relational.core.mapping.event.AfterConvertEvent;
3537
import org.springframework.data.relational.core.mapping.event.AfterLoadCallback;
3638
import org.springframework.data.relational.core.mapping.event.AfterLoadEvent;
3739
import org.springframework.data.repository.core.NamedQueries;
@@ -157,9 +159,11 @@ public T mapRow(ResultSet rs, int rowNum) throws SQLException {
157159
if (entity != null) {
158160

159161
publisher.publishEvent(new AfterLoadEvent<>(entity));
162+
publisher.publishEvent(new AfterConvertEvent<>(entity));
160163

161164
if (callbacks != null) {
162-
return callbacks.callback(AfterLoadCallback.class, entity);
165+
entity = callbacks.callback(AfterLoadCallback.class, entity);
166+
return callbacks.callback(AfterConvertCallback.class, entity);
163167
}
164168
}
165169

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.springframework.data.relational.core.mapping.Column;
4242
import org.springframework.data.relational.core.mapping.NamingStrategy;
4343
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
44+
import org.springframework.data.relational.core.mapping.event.AfterConvertCallback;
4445
import org.springframework.data.relational.core.mapping.event.AfterDeleteCallback;
4546
import org.springframework.data.relational.core.mapping.event.AfterLoadCallback;
4647
import org.springframework.data.relational.core.mapping.event.AfterSaveCallback;
@@ -136,7 +137,9 @@ public void callbackOnLoad() {
136137
when(dataAccessStrategy.findAll(SampleEntity.class)).thenReturn(asList(alfred1, neumann1));
137138

138139
when(callbacks.callback(any(Class.class), eq(alfred1), any())).thenReturn(alfred2);
140+
when(callbacks.callback(any(Class.class), eq(alfred2), any())).thenReturn(alfred2);
139141
when(callbacks.callback(any(Class.class), eq(neumann1), any())).thenReturn(neumann2);
142+
when(callbacks.callback(any(Class.class), eq(neumann2), any())).thenReturn(neumann2);
140143

141144
Iterable<SampleEntity> all = template.findAll(SampleEntity.class);
142145

@@ -158,12 +161,16 @@ public void callbackOnLoadSorted() {
158161
when(dataAccessStrategy.findAll(SampleEntity.class, Sort.by("name"))).thenReturn(asList(alfred1, neumann1));
159162

160163
when(callbacks.callback(any(Class.class), eq(alfred1), any())).thenReturn(alfred2);
164+
when(callbacks.callback(any(Class.class), eq(alfred2), any())).thenReturn(alfred2);
161165
when(callbacks.callback(any(Class.class), eq(neumann1), any())).thenReturn(neumann2);
166+
when(callbacks.callback(any(Class.class), eq(neumann2), any())).thenReturn(neumann2);
162167

163168
Iterable<SampleEntity> all = template.findAll(SampleEntity.class, Sort.by("name"));
164169

165170
verify(callbacks).callback(AfterLoadCallback.class, alfred1);
171+
verify(callbacks).callback(AfterConvertCallback.class, alfred2);
166172
verify(callbacks).callback(AfterLoadCallback.class, neumann1);
173+
verify(callbacks).callback(AfterConvertCallback.class, neumann2);
167174

168175
assertThat(all).containsExactly(alfred2, neumann2);
169176
}
@@ -180,12 +187,16 @@ public void callbackOnLoadPaged() {
180187
when(dataAccessStrategy.findAll(SampleEntity.class, PageRequest.of(0, 20))).thenReturn(asList(alfred1, neumann1));
181188

182189
when(callbacks.callback(any(Class.class), eq(alfred1), any())).thenReturn(alfred2);
190+
when(callbacks.callback(any(Class.class), eq(alfred2), any())).thenReturn(alfred2);
183191
when(callbacks.callback(any(Class.class), eq(neumann1), any())).thenReturn(neumann2);
192+
when(callbacks.callback(any(Class.class), eq(neumann2), any())).thenReturn(neumann2);
184193

185194
Iterable<SampleEntity> all = template.findAll(SampleEntity.class, PageRequest.of(0, 20));
186195

187196
verify(callbacks).callback(AfterLoadCallback.class, alfred1);
197+
verify(callbacks).callback(AfterConvertCallback.class, alfred2);
188198
verify(callbacks).callback(AfterLoadCallback.class, neumann1);
199+
verify(callbacks).callback(AfterConvertCallback.class, neumann2);
189200

190201
assertThat(all).containsExactly(alfred2, neumann2);
191202
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.springframework.data.jdbc.testing.TestConfiguration;
6060
import org.springframework.data.jdbc.testing.TestDatabaseFeatures;
6161
import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent;
62+
import org.springframework.data.relational.core.mapping.event.AfterConvertEvent;
6263
import org.springframework.data.relational.core.mapping.event.AfterLoadEvent;
6364
import org.springframework.data.repository.CrudRepository;
6465
import org.springframework.data.repository.core.NamedQueries;
@@ -309,7 +310,7 @@ public void queryMethodShouldEmitEvents() {
309310

310311
repository.findAllWithSql();
311312

312-
assertThat(eventListener.events).hasSize(1).hasOnlyElementsOfType(AfterLoadEvent.class);
313+
assertThat(eventListener.events).hasSize(2).hasOnlyElementsOfTypes(AfterLoadEvent.class, AfterConvertEvent.class);
313314
}
314315

315316
@Test // DATAJDBC-318

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,7 @@
5151
import org.springframework.data.relational.core.dialect.H2Dialect;
5252
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
5353
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
54-
import org.springframework.data.relational.core.mapping.event.AfterDeleteEvent;
55-
import org.springframework.data.relational.core.mapping.event.AfterLoadEvent;
56-
import org.springframework.data.relational.core.mapping.event.AfterSaveEvent;
57-
import org.springframework.data.relational.core.mapping.event.BeforeConvertEvent;
58-
import org.springframework.data.relational.core.mapping.event.BeforeDeleteEvent;
59-
import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent;
60-
import org.springframework.data.relational.core.mapping.event.Identifier;
61-
import org.springframework.data.relational.core.mapping.event.RelationalEvent;
62-
import org.springframework.data.relational.core.mapping.event.WithId;
54+
import org.springframework.data.relational.core.mapping.event.*;
6355
import org.springframework.data.repository.PagingAndSortingRepository;
6456
import org.springframework.jdbc.core.JdbcOperations;
6557
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
@@ -198,7 +190,9 @@ public void publishesEventsOnFindAll() {
198190
.extracting(e -> (Class) e.getClass()) //
199191
.containsExactly( //
200192
AfterLoadEvent.class, //
201-
AfterLoadEvent.class //
193+
AfterConvertEvent.class, //
194+
AfterLoadEvent.class, //
195+
AfterConvertEvent.class //
202196
);
203197
}
204198

@@ -217,7 +211,9 @@ public void publishesEventsOnFindAllById() {
217211
.extracting(e -> (Class) e.getClass()) //
218212
.containsExactly( //
219213
AfterLoadEvent.class, //
220-
AfterLoadEvent.class //
214+
AfterConvertEvent.class, //
215+
AfterLoadEvent.class, //
216+
AfterConvertEvent.class //
221217
);
222218
}
223219

@@ -234,7 +230,8 @@ public void publishesEventsOnFindById() {
234230
assertThat(publisher.events) //
235231
.extracting(e -> (Class) e.getClass()) //
236232
.containsExactly( //
237-
AfterLoadEvent.class //
233+
AfterLoadEvent.class, //
234+
AfterConvertEvent.class //
238235
);
239236
}
240237

@@ -253,7 +250,9 @@ public void publishesEventsOnFindAllSorted() {
253250
.extracting(e -> (Class) e.getClass()) //
254251
.containsExactly( //
255252
AfterLoadEvent.class, //
256-
AfterLoadEvent.class //
253+
AfterConvertEvent.class, //
254+
AfterLoadEvent.class, //
255+
AfterConvertEvent.class //
257256
);
258257
}
259258

@@ -273,7 +272,9 @@ public void publishesEventsOnFindAllPaged() {
273272
.extracting(e -> (Class) e.getClass()) //
274273
.containsExactly( //
275274
AfterLoadEvent.class, //
276-
AfterLoadEvent.class //
275+
AfterConvertEvent.class, //
276+
AfterLoadEvent.class, //
277+
AfterConvertEvent.class //
277278
);
278279
}
279280

spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AbstractRelationalEventListener.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public void onApplicationEvent(AbstractRelationalEvent<?> event) {
5757

5858
if (event instanceof AfterLoadEvent) {
5959
onAfterLoad((AfterLoadEvent<E>) event);
60+
} else if (event instanceof AfterConvertEvent) {
61+
onAfterConvert((AfterConvertEvent<E>) event);
6062
} else if (event instanceof AfterDeleteEvent) {
6163
onAfterDelete((AfterDeleteEvent<E>) event);
6264
} else if (event instanceof AfterSaveEvent) {
@@ -110,6 +112,7 @@ protected void onAfterSave(AfterSaveEvent<E> event) {
110112
* Captures {@link AfterLoadEvent}.
111113
*
112114
* @param event will never be {@literal null}.
115+
* @deprecated use {@link #onAfterConvert(AfterConvertEvent)} instead.
113116
*/
114117
protected void onAfterLoad(AfterLoadEvent<E> event) {
115118

@@ -118,6 +121,18 @@ protected void onAfterLoad(AfterLoadEvent<E> event) {
118121
}
119122
}
120123

124+
/**
125+
* Captures {@link AfterConvertEvent}.
126+
*
127+
* @param event will never be {@literal null}.
128+
*/
129+
protected void onAfterConvert(AfterConvertEvent<E> event) {
130+
131+
if (LOG.isDebugEnabled()) {
132+
LOG.debug("onAfterConvert({})", event.getEntity());
133+
}
134+
}
135+
121136
/**
122137
* Captures {@link AfterDeleteEvent}.
123138
*
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2019-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.event;
17+
18+
import org.springframework.data.mapping.callback.EntityCallback;
19+
20+
/**
21+
* An {@link EntityCallback} that gets invoked after an aggregate was converted from the database into an entity.
22+
*
23+
* @author Jens Schauder
24+
* @since 2.6
25+
*/
26+
@FunctionalInterface
27+
public interface AfterConvertCallback<T> extends EntityCallback<T> {
28+
29+
/**
30+
* Entity callback method invoked after an aggregate root was converted. Can return either the same or a modified
31+
* instance of the domain object.
32+
*
33+
* @param aggregate the converted aggregate.
34+
* @return the converted and possibly modified aggregate.
35+
*/
36+
T onAfterConvert(T aggregate);
37+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2017-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.relational.core.mapping.event;
17+
18+
/**
19+
* Gets published after instantiation and setting of all the properties of an entity. This allows to do some
20+
* postprocessing of entities if the entities are mutable. For immutable entities use {@link AfterConvertCallback}.
21+
*
22+
* @author Jens Schauder
23+
* @since 2.6
24+
*/
25+
public class AfterConvertEvent<E> extends RelationalEventWithEntity<E> {
26+
27+
private static final long serialVersionUID = 7343072117054666699L;
28+
29+
/**
30+
* @param entity the newly instantiated entity. Must not be {@literal null}.
31+
*/
32+
public AfterConvertEvent(E entity) {
33+
super(entity);
34+
}
35+
}

spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadCallback.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
* @author Jens Schauder
2424
* @author Mark Paluch
2525
* @since 1.1
26+
* @deprecated Use {@link AfterConvertCallback} instead.
2627
*/
28+
@Deprecated
2729
@FunctionalInterface
2830
public interface AfterLoadCallback<T> extends EntityCallback<T> {
2931

spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/event/AfterLoadEvent.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
* postprocessing of entities if the entities are mutable. For immutable entities use {@link AfterLoadCallback}.
2121
*
2222
* @author Jens Schauder
23+
* @deprecated Use {@link AfterConvertEvent} instead.
2324
*/
25+
@Deprecated
2426
public class AfterLoadEvent<E> extends RelationalEventWithEntity<E> {
2527

2628
private static final long serialVersionUID = 7343072117054666699L;

0 commit comments

Comments
 (0)