I'm trying to save a domain object that inherits its id annotated with @Id @GeneratedValue(strategy = UuidStrategy.class) from a superclass, but get a NullPointerException when I attempt to do the save, even though the Neo4j OGM manual states that this is to be possible (and recommended). (Note that if I move the id to the non-abstract sub-class, the node is happily saved).
The code uses Spring Boot 2.0.0.M7
Edit #2: If I now make the abstract classes concrete (by removing the abstract Keyword), the node is now populated to the database. However, without the abstract keyword, the label of the super-classes are also applied to the node (ie the node has the labels Fan, BaseNodeEntity, and BaseEntity). This could be a (temporary?) workaround to the issue, although I don't know the impact of having these extra labels applied to all the nodes. (Does anyone know?) Or can anyone offer a better solution?
Edit #1 I've moved the abstract classes into the same package as the other nodes so they are correctly scanned, as per the set up of the SessionFactory (for the package "com.ideafan.server.neo4j.node") however I now get an UnsatisfiedDependencyError as follows:
2018-02-04 17:33:01.498 ERROR 15908 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataPopulatorService': Unsatisfied dependency expressed through field 'fanRepository'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fanRepository': Unsatisfied dependency expressed through method 'setSession' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.neo4j.transaction.SharedSessionCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/ideafan/server/PersistenceContext.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:138) ~[spring-boot-2.0.0.M7.jar:2.0.0.M7]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:751) [spring-boot-2.0.0.M7.jar:2.0.0.M7]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:387) [spring-boot-2.0.0.M7.jar:2.0.0.M7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.M7.jar:2.0.0.M7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) [spring-boot-2.0.0.M7.jar:2.0.0.M7]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233) [spring-boot-2.0.0.M7.jar:2.0.0.M7]
at com.ideafan.server.IdeaFanServerApplication.main(IdeaFanServerApplication.java:14) [classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fanRepository': Unsatisfied dependency expressed through method 'setSession' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.neo4j.transaction.SharedSessionCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/ideafan/server/PersistenceContext.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:667) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:583) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.neo4j.transaction.SharedSessionCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/ideafan/server/PersistenceContext.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:622) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:440) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:659) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 32 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [com/ideafan/server/PersistenceContext.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 47 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 56 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.neo4j.ogm.autoindex.AutoIndex.<init>(AutoIndex.java:39) ~[neo4j-ogm-core-3.0.2.jar:na]
at org.neo4j.ogm.autoindex.AutoIndexManager.initialiseIndexMetadata(AutoIndexManager.java:74) ~[neo4j-ogm-core-3.0.2.jar:na]
at org.neo4j.ogm.autoindex.AutoIndexManager.<init>(AutoIndexManager.java:59) ~[neo4j-ogm-core-3.0.2.jar:na]
at org.neo4j.ogm.session.SessionFactory.<init>(SessionFactory.java:83) ~[neo4j-ogm-core-3.0.2.jar:na]
at com.ideafan.server.PersistenceContext.sessionFactory(PersistenceContext.java:27) ~[classes/:na]
at com.ideafan.server.PersistenceContext$$EnhancerBySpringCGLIB$$a83ca23f.CGLIB$sessionFactory$2(<generated>) ~[classes/:na]
at com.ideafan.server.PersistenceContext$$EnhancerBySpringCGLIB$$a83ca23f$$FastClassBySpringCGLIB$$8bf83868.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at com.ideafan.server.PersistenceContext$$EnhancerBySpringCGLIB$$a83ca23f.sessionFactory(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 57 common frames omitted
Domain classes:
Fan.java
package com.ideafan.server.neo4j.node;
import org.neo4j.ogm.annotation.NodeEntity;
import com.ideafan.server.neo4j.BaseNodeEntity;
@NodeEntity
public class Fan extends BaseNodeEntity {
String firstName;
public Fan() {}
public Fan(String firstName) {
super();
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
BaseNodeEntity.java
public abstract class BaseNodeEntity extends BaseEntity {
}
BaseEntity.java
package com.ideafan.server.neo4j;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.id.UuidStrategy;
public abstract class BaseEntity {
@Id @GeneratedValue(strategy = UuidStrategy.class)
private String uuid;
}
FanRepository.java
@Repository
public interface FanRepository extends Neo4jRepository<Fan, String> {
Fan findByFirstName(String firstName);
}
Business-logic classes:
IdeaFanServerApplication.java
@SpringBootApplication
public class IdeaFanServerApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(IdeaFanServerApplication.class, args);
DataPopulatorService dataPopulatorService = applicationContext.getBean(DataPopulatorService.class);
dataPopulatorService.populateSampleData();
}
}
DataPopulatorService.java
@Service
@Transactional
public class DataPopulatorService {
private Logger logger = LogManager.getLogger();
@Autowired private FanRepository fanRepository;
public void populateSampleData() {
Fan fan = new Fan("Fan");
fanRepository.save(fan);
}
}
Configuration:
AppConfig.java
@Configuration
@ComponentScan({"com.ideafan.server.controller"})
public class AppConfig {
@Bean
public DataPopulatorService dataPopulatorService() {
return new DataPopulatorService();
}
}
PersistenceContext.java
@Configuration
@ComponentScan("com.ideafan.server.neo4j")
@EnableNeo4jRepositories(basePackages = "com.ideafan.server.neo4j.repository")
@EnableTransactionManagement
public class PersistenceContext {
@Bean
public SessionFactory sessionFactory() {
// with domain entity base package(s)
return new SessionFactory(configuration(), "com.ideafan.server.neo4j.node");
}
@Bean
public org.neo4j.ogm.config.Configuration configuration() {
// Configuration reference: https://neo4j.com/docs/ogm-manual/current/reference/#reference:configuration
org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder()
.uri("bolt://neo4j:password@localhost") // Note: neo4j is the username and password is the password.
.build();
return configuration;
}
@Bean
public Neo4jTransactionManager transactionManager() throws Exception {
return new Neo4jTransactionManager(sessionFactory());
}
}
Log (with errors):
2018-02-04 16:34:49.207 INFO 11112 --- [ main] c.i.server.IdeaFanServerApplication : Started IdeaFanServerApplication in 4.531 seconds (JVM running for 5.55)
Exception in thread "main" java.lang.NullPointerException
at org.neo4j.ogm.context.MappingContext.nativeId(MappingContext.java:478)
at org.neo4j.ogm.context.EntityGraphMapper.getNodeBuilder(EntityGraphMapper.java:278)
at org.neo4j.ogm.context.EntityGraphMapper.mapEntity(EntityGraphMapper.java:216)
at org.neo4j.ogm.context.EntityGraphMapper.map(EntityGraphMapper.java:127)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:80)
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:41)
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:451)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:131)
at com.sun.proxy.$Proxy64.save(Unknown Source)
at org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.save(SimpleNeo4jRepository.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:636)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:600)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:580)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy70.save(Unknown Source)
at com.ideafan.server.service.admin.datapopulator.DataPopulatorService.populateSampleData(DataPopulatorService.java:25)
at com.ideafan.server.service.admin.datapopulator.DataPopulatorService$$FastClassBySpringCGLIB$$dd77d09f.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.ideafan.server.service.admin.datapopulator.DataPopulatorService$$EnhancerBySpringCGLIB$$4185cb29.populateSampleData(<generated>)
at com.ideafan.server.IdeaFanServerApplication.main(IdeaFanServerApplication.java:18)
The error apparently happens when an Entity is used without an id as per this issue on the ogm issue-tracker.
If I instead of putting the @Id @GeneratedValue id field in the abstract superclass, but instead put it in the concrete sub-class, then the node gets written to the database without a problem.
Modified domain class:
Fan.java package com.ideafan.server.neo4j.node;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.id.UuidStrategy;
@NodeEntity
public class Fan /*extends BaseNodeEntity*/ {
@Id @GeneratedValue(strategy = UuidStrategy.class)
private String id;
String firstName;
public Fan() {}
public Fan(String firstName) {
super();
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
Log (without errors):
2018-02-04 16:10:25.373 INFO 11892 --- [ main] c.i.server.IdeaFanServerApplication : Started IdeaFanServerApplication in 4.952 seconds (JVM running for 5.751)
2018-02-04 16:10:25.842 INFO 11892 --- [ main] o.n.o.drivers.bolt.request.BoltRequest : Request: UNWIND {rows} as row MERGE (n:`Fan`{id: row.props.id}) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type with params {rows=[{nodeRef=-1, type=node, props={firstName=Fan, id=45a22c54-27a0-47af-bb8e-f4b9d3195d94}}]}
Can anyone see what the issue might be?
All node classes should be in same package in order to get scanned, try moving all classes to same package as class Fan
. In short, in this package:
new SessionFactory(configuration(), "com.ideafan.server.neo4j.node");
Update: While putting @Id
field in base abstract class, make sure you also annotate base abstract class with @NodeEntity
as per this discussion.