diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jOgmEntityInstantiatorConfigurationBean.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jOgmEntityInstantiatorConfigurationBean.java index 6f4469080..96cf14333 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jOgmEntityInstantiatorConfigurationBean.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jOgmEntityInstantiatorConfigurationBean.java @@ -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 conversionServiceObjectProvider) { + private final SessionFactory sessionFactory; + private final Neo4jMappingContext mappingContext; + private final ObjectProvider conversionServiceObjectProvider; + public Neo4jOgmEntityInstantiatorConfigurationBean( + SessionFactory sessionFactory, Neo4jMappingContext mappingContext, + ObjectProvider 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)); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jRepositoryConfigurationExtension.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jRepositoryConfigurationExtension.java index 02a7650f2..68b8b909d 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jRepositoryConfigurationExtension.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/repository/config/Neo4jRepositoryConfigurationExtension.java @@ -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