16
16
package org .springframework .data .jdbc .repository .support ;
17
17
18
18
import org .springframework .beans .BeanUtils ;
19
+ import org .springframework .context .ApplicationEventPublisher ;
19
20
import org .springframework .dao .EmptyResultDataAccessException ;
20
21
import org .springframework .data .relational .core .mapping .RelationalMappingContext ;
22
+ import org .springframework .data .relational .core .mapping .RelationalPersistentEntity ;
23
+ import org .springframework .data .relational .core .mapping .event .AfterLoadEvent ;
24
+ import org .springframework .data .relational .core .mapping .event .Identifier ;
21
25
import org .springframework .data .repository .query .RepositoryQuery ;
22
26
import org .springframework .jdbc .core .RowMapper ;
23
27
import org .springframework .jdbc .core .namedparam .MapSqlParameterSource ;
26
30
import org .springframework .util .Assert ;
27
31
import org .springframework .util .StringUtils ;
28
32
33
+ import java .util .List ;
34
+
29
35
/**
30
36
* A query to be executed based on a repository method, it's annotated SQL query and the arguments provided to the
31
37
* method.
32
38
*
33
39
* @author Jens Schauder
34
40
* @author Kazuki Shimizu
35
41
* @author Oliver Gierke
42
+ * @author Maciej Walkowiak
36
43
*/
37
44
class JdbcRepositoryQuery implements RepositoryQuery {
38
45
39
46
private static final String PARAMETER_NEEDS_TO_BE_NAMED = "For queries with named parameters you need to provide names for method parameters. Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters." ;
40
47
48
+ private final ApplicationEventPublisher publisher ;
49
+ private final RelationalMappingContext context ;
41
50
private final JdbcQueryMethod queryMethod ;
42
51
private final NamedParameterJdbcOperations operations ;
43
52
private final RowMapper <?> rowMapper ;
44
53
45
54
/**
46
55
* Creates a new {@link JdbcRepositoryQuery} for the given {@link JdbcQueryMethod}, {@link RelationalMappingContext} and
47
56
* {@link RowMapper}.
48
- *
57
+ *
58
+ * @param publisher must not be {@literal null}.
59
+ * @param context must not be {@literal null}.
49
60
* @param queryMethod must not be {@literal null}.
50
61
* @param operations must not be {@literal null}.
51
62
* @param defaultRowMapper can be {@literal null} (only in case of a modifying query).
52
63
*/
53
- JdbcRepositoryQuery (JdbcQueryMethod queryMethod , NamedParameterJdbcOperations operations ,
64
+ JdbcRepositoryQuery (ApplicationEventPublisher publisher , RelationalMappingContext context , JdbcQueryMethod queryMethod , NamedParameterJdbcOperations operations ,
54
65
@ Nullable RowMapper <?> defaultRowMapper ) {
55
66
67
+ Assert .notNull (publisher , "Publisher must not be null!" );
68
+ Assert .notNull (context , "Context must not be null!" );
56
69
Assert .notNull (queryMethod , "Query method must not be null!" );
57
70
Assert .notNull (operations , "NamedParameterJdbcOperations must not be null!" );
58
71
59
72
if (!queryMethod .isModifyingQuery ()) {
60
73
Assert .notNull (defaultRowMapper , "RowMapper must not be null!" );
61
74
}
62
75
76
+ this .publisher = publisher ;
77
+ this .context = context ;
63
78
this .queryMethod = queryMethod ;
64
79
this .operations = operations ;
65
80
this .rowMapper = createRowMapper (queryMethod , defaultRowMapper );
@@ -84,11 +99,15 @@ public Object execute(Object[] objects) {
84
99
}
85
100
86
101
if (queryMethod .isCollectionQuery () || queryMethod .isStreamQuery ()) {
87
- return operations .query (query , parameters , rowMapper );
102
+ List <?> result = operations .query (query , parameters , rowMapper );
103
+ publishAfterLoad (result );
104
+ return result ;
88
105
}
89
106
90
107
try {
91
- return operations .queryForObject (query , parameters , rowMapper );
108
+ Object result = operations .queryForObject (query , parameters , rowMapper );
109
+ publishAfterLoad (result );
110
+ return result ;
92
111
} catch (EmptyResultDataAccessException e ) {
93
112
return null ;
94
113
}
@@ -136,4 +155,25 @@ private static RowMapper<?> createRowMapper(JdbcQueryMethod queryMethod, @Nullab
136
155
? defaultRowMapper //
137
156
: (RowMapper <?>) BeanUtils .instantiateClass (rowMapperClass );
138
157
}
158
+
159
+ private <T > void publishAfterLoad (Iterable <T > all ) {
160
+
161
+ for (T e : all ) {
162
+ publishAfterLoad (e );
163
+ }
164
+ }
165
+
166
+ private <T > void publishAfterLoad (@ Nullable T entity ) {
167
+
168
+ if (entity != null && context .hasPersistentEntityFor (entity .getClass ())) {
169
+ RelationalPersistentEntity <?> e = context .getRequiredPersistentEntity (entity .getClass ());
170
+ Object identifier = e .getIdentifierAccessor (entity )
171
+ .getIdentifier ();
172
+
173
+ if (identifier != null ) {
174
+ publisher .publishEvent (new AfterLoadEvent (Identifier .of (identifier ), entity ));
175
+ }
176
+ }
177
+
178
+ }
139
179
}
0 commit comments