GH-2099 - Declare the dependency between shared session creator and entity instantiator.
The conversion service is picked up to late as the the dependency between the shared session creator and the bean that does the post processing of the underlying session factory is undefined for the Spring context. By explicit stating this in the repository extension, the `Neo4jOgmEntityInstantiatorConfigurationBean` is correctly initialized upfront without messing around with an actual post processor or orderings. This closes #2099.
This commit is contained in:
@@ -15,25 +15,44 @@
|
||||
*/
|
||||
package org.springframework.data.neo4j.repository.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.neo4j.ogm.metadata.MetaData;
|
||||
import org.neo4j.ogm.session.SessionFactory;
|
||||
import org.neo4j.ogm.typeconversion.ConversionCallback;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.neo4j.conversion.MetaDataDrivenConversionService;
|
||||
import org.springframework.data.neo4j.conversion.Neo4jOgmEntityInstantiatorAdapter;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jMappingContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Gerrit Meier
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
class Neo4jOgmEntityInstantiatorConfigurationBean {
|
||||
class Neo4jOgmEntityInstantiatorConfigurationBean implements InitializingBean {
|
||||
|
||||
public Neo4jOgmEntityInstantiatorConfigurationBean(SessionFactory sessionFactory, Neo4jMappingContext mappingContext,
|
||||
ObjectProvider<ConversionService> conversionServiceObjectProvider) {
|
||||
private final SessionFactory sessionFactory;
|
||||
private final Neo4jMappingContext mappingContext;
|
||||
private final ObjectProvider<ConversionService> conversionServiceObjectProvider;
|
||||
|
||||
public Neo4jOgmEntityInstantiatorConfigurationBean(
|
||||
SessionFactory sessionFactory, Neo4jMappingContext mappingContext,
|
||||
ObjectProvider<ConversionService> conversionServiceObjectProvider
|
||||
) {
|
||||
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.mappingContext = mappingContext;
|
||||
this.conversionServiceObjectProvider = conversionServiceObjectProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
MetaData metaData = sessionFactory.metaData();
|
||||
ConversionService conversionService = conversionServiceObjectProvider
|
||||
.getIfUnique(() -> new MetaDataDrivenConversionService(metaData));
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.Optional;
|
||||
|
||||
import org.neo4j.ogm.annotation.NodeEntity;
|
||||
import org.neo4j.ogm.annotation.RelationshipEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
@@ -189,23 +191,29 @@ public class Neo4jRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
return;
|
||||
}
|
||||
|
||||
String configuredSessionBeanName = config.getAttribute("sessionBeanName").orElse(GENERATE_BEAN_NAME);
|
||||
this.sessionBeanName = registerWithGeneratedNameOrUseConfigured(createSharedSessionCreatorBeanDefinition(config),
|
||||
registry, configuredSessionBeanName, source);
|
||||
|
||||
String configuredMappingContextBeanName = config.getAttribute("mappingContextBeanName").orElse(GENERATE_BEAN_NAME);
|
||||
String configuredSessionBeanName = config.getAttribute("sessionBeanName").orElse(GENERATE_BEAN_NAME);
|
||||
|
||||
// Register mapping context
|
||||
this.neo4jMappingContextBeanName = registerWithGeneratedNameOrUseConfigured(
|
||||
createNeo4jMappingContextFactoryBeanDefinition(config), registry, configuredMappingContextBeanName, source);
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> new RootBeanDefinition(Neo4jPersistenceExceptionTranslator.class), registry,
|
||||
NEO4J_PERSISTENCE_EXCEPTION_TRANSLATOR_NAME, source);
|
||||
|
||||
// Prepare session factory postprocessor
|
||||
AbstractBeanDefinition rootBeanDefinition = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(Neo4jOgmEntityInstantiatorConfigurationBean.class)
|
||||
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
|
||||
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR)
|
||||
.addConstructorArgReference(getSessionFactoryBeanName(config))
|
||||
.addConstructorArgReference(this.neo4jMappingContextBeanName).getBeanDefinition();
|
||||
registerWithGeneratedNameOrUseConfigured(rootBeanDefinition, registry, GENERATE_BEAN_NAME, source);
|
||||
.addConstructorArgReference(this.neo4jMappingContextBeanName)
|
||||
.getBeanDefinition();
|
||||
String sessionFactoryPostProcessorBeanName = registerWithGeneratedNameOrUseConfigured(
|
||||
rootBeanDefinition, registry, GENERATE_BEAN_NAME, source);
|
||||
|
||||
// Make sure the shared session creator depends on it
|
||||
this.sessionBeanName = registerWithGeneratedNameOrUseConfigured(
|
||||
createSharedSessionCreatorBeanDefinition(config, sessionFactoryPostProcessorBeanName), registry, configuredSessionBeanName, source);
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> new RootBeanDefinition(Neo4jPersistenceExceptionTranslator.class), registry,
|
||||
NEO4J_PERSISTENCE_EXCEPTION_TRANSLATOR_NAME, source);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,13 +244,17 @@ public class Neo4jRepositoryConfigurationExtension extends RepositoryConfigurati
|
||||
return registeredBeanName;
|
||||
}
|
||||
|
||||
private static AbstractBeanDefinition createSharedSessionCreatorBeanDefinition(RepositoryConfigurationSource config) {
|
||||
private static AbstractBeanDefinition createSharedSessionCreatorBeanDefinition(
|
||||
RepositoryConfigurationSource config,
|
||||
String sessionFactoryPostProcessorBeanName
|
||||
) {
|
||||
|
||||
String sessionFactoryBeanName = getSessionFactoryBeanName(config);
|
||||
|
||||
AbstractBeanDefinition sharedSessionCreatorBeanDefinition = BeanDefinitionBuilder //
|
||||
.rootBeanDefinition(SharedSessionCreator.class, "createSharedSession") //
|
||||
.addConstructorArgReference(sessionFactoryBeanName) //
|
||||
.addDependsOn(sessionFactoryPostProcessorBeanName)
|
||||
.getBeanDefinition();
|
||||
|
||||
sharedSessionCreatorBeanDefinition
|
||||
|
||||
Reference in New Issue
Block a user