@ -16,6 +16,9 @@
@@ -16,6 +16,9 @@
package org.springframework.data.jdbc.repository.support ;
import java.io.Serializable ;
import org.jspecify.annotations.Nullable ;
import org.springframework.beans.factory.BeanFactory ;
import org.springframework.context.ApplicationEventPublisher ;
import org.springframework.context.ApplicationEventPublisherAware ;
@ -38,6 +41,19 @@ import org.springframework.util.Assert;
@@ -38,6 +41,19 @@ import org.springframework.util.Assert;
/ * *
* Special adapter for Springs { @link org . springframework . beans . factory . FactoryBean } interface to allow easy setup of
* repository factories via Spring configuration .
* < p >
* A partially populated factory bean can use { @link BeanFactory } to resolve missing dependencies , specifically :
* < ul >
* < li > The { @link org . springframework . data . mapping . context . MappingContext } is being derived from
* { @link RelationalMappingContext } if the { @code mappingContext } was not set . < / li >
* < li > The { @link NamedParameterJdbcOperations } is looked up from a { @link BeanFactory } if { @code jdbcOperations } was
* not set . < / li >
* < li > The { @link QueryMappingConfiguration } is looked up from a { @link BeanFactory } if
* { @code queryMappingConfiguration } was not set . If the { @link BeanFactory } was not set , defaults to
* { @link QueryMappingConfiguration # EMPTY } . < / li >
* < li > The { @link DataAccessStrategy } is looked up from a { @link BeanFactory } if { @code dataAccessStrategy } was not set .
* If the { @link BeanFactory } was not set , then it is created using { @link Dialect } . < / li >
* < / ul >
*
* @author Jens Schauder
* @author Greg Turnquist
@ -52,15 +68,15 @@ import org.springframework.util.Assert;
@@ -52,15 +68,15 @@ import org.springframework.util.Assert;
public class JdbcRepositoryFactoryBean < T extends Repository < S , ID > , S , ID extends Serializable >
extends TransactionalRepositoryFactoryBeanSupport < T , S , ID > implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher ;
private BeanFactory beanFactory ;
private RelationalMappingContext mappingContext ;
private JdbcConverter converter ;
private DataAccessStrategy dataAccessStrategy ;
private QueryMappingConfiguration queryMappingConfiguration ;
private NamedParameterJdbcOperations operations ;
private EntityCallbacks entityCallbacks ;
private Dialect dialect ;
private @Nullable ApplicationEventPublisher publisher ;
private @Nullable BeanFactory beanFactory ;
private @Nullable RelationalMappingContext mappingContext ;
private @Nullable JdbcConverter converter ;
private @Nullable DataAccessStrategy dataAccessStrategy ;
private @Nullable QueryMappingConfiguration queryMappingConfiguration ;
private @Nullable NamedParameterJdbcOperations operations ;
private EntityCallbacks entityCallbacks = EntityCallbacks . create ( ) ;
private @Nullable Dialect dialect ;
/ * *
* Creates a new { @link JdbcRepositoryFactoryBean } for the given repository interface .
@ -85,6 +101,14 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
@@ -85,6 +101,14 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
@Override
protected RepositoryFactorySupport doCreateRepositoryFactory ( ) {
Assert . state ( this . dataAccessStrategy ! = null , "DataAccessStrategy is required and must not be null" ) ;
Assert . state ( this . mappingContext ! = null , "MappingContext is required and must not be null" ) ;
Assert . state ( this . converter ! = null , "RelationalConverter is required and must not be null" ) ;
Assert . state ( this . dialect ! = null , "Dialect is required and must not be null" ) ;
Assert . state ( this . publisher ! = null , "ApplicationEventPublisher is required and must not be null" ) ;
Assert . state ( this . operations ! = null , "NamedParameterJdbcOperations is required and must not be null" ) ;
Assert . state ( this . queryMappingConfiguration ! = null , "RelationalConverter is required and must not be null" ) ;
JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory ( dataAccessStrategy , mappingContext ,
converter , dialect , publisher , operations ) ;
jdbcRepositoryFactory . setQueryMappingConfiguration ( queryMappingConfiguration ) ;
@ -149,6 +173,7 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
@@ -149,6 +173,7 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
super . setBeanFactory ( beanFactory ) ;
this . entityCallbacks = EntityCallbacks . create ( beanFactory ) ;
this . beanFactory = beanFactory ;
}
@ -157,51 +182,53 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
@@ -157,51 +182,53 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
Assert . state ( this . converter ! = null , "RelationalConverter is required and must not be null" ) ;
if ( mappingContext = = null ) {
Assert . state ( beanFactory ! = null , "If no MappingContext are set a BeanFactory must be available" ) ;
this . mappingContext = beanFactory . getBean ( RelationalMappingContext . class ) ;
if ( this . mappingContext = = null ) {
this . mappingContext = this . converter . getMappingContext ( ) ;
}
if ( this . operations = = null ) {
Assert . state ( beanFactory ! = null , "If no JdbcOperations are set a BeanFactory must be available" ) ;
this . operations = beanFactory . getBean ( NamedParameterJdbcOperations . class ) ;
Assert . state ( this . beanFactory ! = null , "If no JdbcOperations are set a BeanFactory must be available" ) ;
this . operations = this . beanFactory . getBean ( NamedParameterJdbcOperations . class ) ;
}
if ( this . queryMappingConfiguration = = null ) {
Assert . state ( beanFactory ! = null , "If no QueryMappingConfiguration are set a BeanFactory must be available" ) ;
this . queryMappingConfiguration = beanFactory . getBeanProvider ( QueryMappingConfiguration . class )
. getIfAvailable ( ( ) - > QueryMappingConfiguration . EMPTY ) ;
if ( this . beanFactory = = null ) {
this . queryMappingConfiguration = QueryMappingConfiguration . EMPTY ;
} else {
this . queryMappingConfiguration = beanFactory . getBeanProvider ( QueryMappingConfiguration . class )
. getIfAvailable ( ( ) - > QueryMappingConfiguration . EMPTY ) ;
}
}
if ( this . dataAccessStrategy = = null ) {
if ( this . dataAccessStrategy = = null & & this . beanFactory ! = null ) {
this . dataAccessStrategy = this . beanFactory . getBeanProvider ( DataAccessStrategy . class ) . getIfAvailable ( ) ;
}
Assert . state ( beanFactory ! = null , "If no DataAccessStrategy is set a BeanFactory must be available" ) ;
if ( this . dataAccessStrategy = = null ) {
this . dataAccessStrategy = this . beanFactory . getBeanProvider ( DataAccessStrategy . class ) //
. getIfAvailable ( ( ) - > {
Assert . state ( this . dialect ! = null , "Dialect is required and must not be null" ) ;
Assert . state ( this . dialect ! = null , "Dialect is required and must not be null" ) ;
DataAccessStrategyFactory factory = getDataAccessStrategyFactory ( this . mappingContext , this . converter ,
this . dialect , this . operations , this . queryMappingConfiguration ) ;
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource ( this . mappingContext , this . converter ,
this . dialect ) ;
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory ( this . mappingContext , this . converter ) ;
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory ( this . operations , this . dialect ) ;
this . dataAccessStrategy = factory . create ( ) ;
}
DataAccessStrategyFactory factory = new DataAccessStrategyFactory ( sqlGeneratorSource , this . converter ,
this . operations , sqlParametersFactory , insertStrategyFactory , queryMappingConfiguration ) ;
super . afterPropertiesSet ( ) ;
}
return factory . create ( ) ;
} ) ;
}
private static DataAccessStrategyFactory getDataAccessStrategyFactory ( RelationalMappingContext mappingContext ,
JdbcConverter converter , Dialect dialect , NamedParameterJdbcOperations operations ,
QueryMappingConfiguration queryMapping ) {
if ( beanFactory ! = null ) {
entityCallbacks = EntityCallbacks . create ( beanFactory ) ;
}
SqlGeneratorSource source = new SqlGeneratorSource ( mappingContext , converter , dialect ) ;
SqlParametersFactory spf = new SqlParametersFactory ( mappingContext , converter ) ;
InsertStrategyFactory isf = new InsertStrategyFactory ( operations , dialect ) ;
super . afterPropertiesSet ( ) ;
return new DataAccessStrategyFactory ( source , converter , operations , spf , isf , queryMapping ) ;
}
}