1616package org .springframework .data .jdbc .repository .support ;
1717
1818import java .io .Serializable ;
19+
20+ import org .jspecify .annotations .Nullable ;
21+
1922import org .springframework .beans .factory .BeanFactory ;
2023import org .springframework .context .ApplicationEventPublisher ;
2124import org .springframework .context .ApplicationEventPublisherAware ;
3841/**
3942 * Special adapter for Springs {@link org.springframework.beans.factory.FactoryBean} interface to allow easy setup of
4043 * repository factories via Spring configuration.
44+ * <p>
45+ * A partially populated factory bean can use {@link BeanFactory} to resolve missing dependencies, specifically:
46+ * <ul>
47+ * <li>The {@link org.springframework.data.mapping.context.MappingContext} is being derived from
48+ * {@link RelationalMappingContext} if the {@code mappingContext} was not set.</li>
49+ * <li>The {@link NamedParameterJdbcOperations} is looked up from a {@link BeanFactory} if {@code jdbcOperations} was
50+ * not set.</li>
51+ * <li>The {@link QueryMappingConfiguration} is looked up from a {@link BeanFactory} if
52+ * {@code queryMappingConfiguration} was not set. If the {@link BeanFactory} was not set, defaults to
53+ * {@link QueryMappingConfiguration#EMPTY}.</li>
54+ * <li>The {@link DataAccessStrategy} is looked up from a {@link BeanFactory} if {@code dataAccessStrategy} was not set.
55+ * If the {@link BeanFactory} was not set, then it is created using {@link Dialect}.</li>
56+ * </ul>
4157 *
4258 * @author Jens Schauder
4359 * @author Greg Turnquist
5268public class JdbcRepositoryFactoryBean <T extends Repository <S , ID >, S , ID extends Serializable >
5369 extends TransactionalRepositoryFactoryBeanSupport <T , S , ID > implements ApplicationEventPublisherAware {
5470
55- private ApplicationEventPublisher publisher ;
56- private BeanFactory beanFactory ;
57- private RelationalMappingContext mappingContext ;
58- private JdbcConverter converter ;
59- private DataAccessStrategy dataAccessStrategy ;
60- private QueryMappingConfiguration queryMappingConfiguration ;
61- private NamedParameterJdbcOperations operations ;
62- private EntityCallbacks entityCallbacks ;
63- private Dialect dialect ;
71+ private @ Nullable ApplicationEventPublisher publisher ;
72+ private @ Nullable BeanFactory beanFactory ;
73+ private @ Nullable RelationalMappingContext mappingContext ;
74+ private @ Nullable JdbcConverter converter ;
75+ private @ Nullable DataAccessStrategy dataAccessStrategy ;
76+ private @ Nullable QueryMappingConfiguration queryMappingConfiguration ;
77+ private @ Nullable NamedParameterJdbcOperations operations ;
78+ private EntityCallbacks entityCallbacks = EntityCallbacks . create () ;
79+ private @ Nullable Dialect dialect ;
6480
6581 /**
6682 * Creates a new {@link JdbcRepositoryFactoryBean} for the given repository interface.
@@ -85,6 +101,14 @@ public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
85101 @ Override
86102 protected RepositoryFactorySupport doCreateRepositoryFactory () {
87103
104+ Assert .state (this .dataAccessStrategy != null , "DataAccessStrategy is required and must not be null" );
105+ Assert .state (this .mappingContext != null , "MappingContext is required and must not be null" );
106+ Assert .state (this .converter != null , "RelationalConverter is required and must not be null" );
107+ Assert .state (this .dialect != null , "Dialect is required and must not be null" );
108+ Assert .state (this .publisher != null , "ApplicationEventPublisher is required and must not be null" );
109+ Assert .state (this .operations != null , "NamedParameterJdbcOperations is required and must not be null" );
110+ Assert .state (this .queryMappingConfiguration != null , "RelationalConverter is required and must not be null" );
111+
88112 JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory (dataAccessStrategy , mappingContext ,
89113 converter , dialect , publisher , operations );
90114 jdbcRepositoryFactory .setQueryMappingConfiguration (queryMappingConfiguration );
@@ -149,6 +173,7 @@ public void setBeanFactory(BeanFactory beanFactory) {
149173
150174 super .setBeanFactory (beanFactory );
151175
176+ this .entityCallbacks = EntityCallbacks .create (beanFactory );
152177 this .beanFactory = beanFactory ;
153178 }
154179
@@ -157,51 +182,53 @@ public void afterPropertiesSet() {
157182
158183 Assert .state (this .converter != null , "RelationalConverter is required and must not be null" );
159184
160- if (mappingContext == null ) {
161- Assert .state (beanFactory != null , "If no MappingContext are set a BeanFactory must be available" );
162-
163- this .mappingContext = beanFactory .getBean (RelationalMappingContext .class );
185+ if (this .mappingContext == null ) {
186+ this .mappingContext = this .converter .getMappingContext ();
164187 }
165188
166189 if (this .operations == null ) {
167190
168- Assert .state (beanFactory != null , "If no JdbcOperations are set a BeanFactory must be available" );
169-
170- this .operations = beanFactory .getBean (NamedParameterJdbcOperations .class );
191+ Assert .state (this .beanFactory != null , "If no JdbcOperations are set a BeanFactory must be available" );
192+ this .operations = this .beanFactory .getBean (NamedParameterJdbcOperations .class );
171193 }
172194
173195 if (this .queryMappingConfiguration == null ) {
174- Assert .state (beanFactory != null , "If no QueryMappingConfiguration are set a BeanFactory must be available" );
175196
176- this .queryMappingConfiguration = beanFactory .getBeanProvider (QueryMappingConfiguration .class )
177- .getIfAvailable (() -> QueryMappingConfiguration .EMPTY );
197+ if (this .beanFactory == null ) {
198+ this .queryMappingConfiguration = QueryMappingConfiguration .EMPTY ;
199+ } else {
200+
201+ this .queryMappingConfiguration = beanFactory .getBeanProvider (QueryMappingConfiguration .class )
202+ .getIfAvailable (() -> QueryMappingConfiguration .EMPTY );
203+ }
178204 }
179205
180- if (this .dataAccessStrategy == null ) {
206+ if (this .dataAccessStrategy == null && this .beanFactory != null ) {
207+ this .dataAccessStrategy = this .beanFactory .getBeanProvider (DataAccessStrategy .class ).getIfAvailable ();
208+ }
181209
182- Assert . state ( beanFactory != null , "If no DataAccessStrategy is set a BeanFactory must be available" );
210+ if ( this . dataAccessStrategy == null ) {
183211
184- this .dataAccessStrategy = this .beanFactory .getBeanProvider (DataAccessStrategy .class ) //
185- .getIfAvailable (() -> {
212+ Assert .state (this .dialect != null , "Dialect is required and must not be null" );
186213
187- Assert .state (this .dialect != null , "Dialect is required and must not be null" );
214+ DataAccessStrategyFactory factory = getDataAccessStrategyFactory (this .mappingContext , this .converter ,
215+ this .dialect , this .operations , this .queryMappingConfiguration );
188216
189- SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource (this .mappingContext , this .converter ,
190- this .dialect );
191- SqlParametersFactory sqlParametersFactory = new SqlParametersFactory (this .mappingContext , this .converter );
192- InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory (this .operations , this .dialect );
217+ this .dataAccessStrategy = factory .create ();
218+ }
193219
194- DataAccessStrategyFactory factory = new DataAccessStrategyFactory ( sqlGeneratorSource , this . converter ,
195- this . operations , sqlParametersFactory , insertStrategyFactory , queryMappingConfiguration );
220+ super . afterPropertiesSet ();
221+ }
196222
197- return factory . create ();
198- });
199- }
223+ private static DataAccessStrategyFactory getDataAccessStrategyFactory ( RelationalMappingContext mappingContext ,
224+ JdbcConverter converter , Dialect dialect , NamedParameterJdbcOperations operations ,
225+ QueryMappingConfiguration queryMapping ) {
200226
201- if ( beanFactory != null ) {
202- entityCallbacks = EntityCallbacks . create ( beanFactory );
203- }
227+ SqlGeneratorSource source = new SqlGeneratorSource ( mappingContext , converter , dialect );
228+ SqlParametersFactory spf = new SqlParametersFactory ( mappingContext , converter );
229+ InsertStrategyFactory isf = new InsertStrategyFactory ( operations , dialect );
204230
205- super . afterPropertiesSet ( );
231+ return new DataAccessStrategyFactory ( source , converter , operations , spf , isf , queryMapping );
206232 }
233+
207234}
0 commit comments