Spring 数据 Neo4j 存储库调用 init 方法失败

Spring Data Neo4j repository Invocation of init method failed

我有一个 Spring Data Neo4j 项目,它将成为 Spring MVC 使用的数据访问对象。

我只是希望针对内存数据库进行单元测试 运行,而在生产中它必须连接到远程服务器。

显然,根据我问的另一个问题的答案,远程服务器访问仅在 Spring Data Neo4j 4.0.0.M1 中可用,但由于这是一个移动的目标,所以事情不断发生变化。

为了让它至少能够编译,我使用的是 4.0.0.BUILD-SNAPSHOT

当 运行 进行测试时,我现在得到以下信息:

Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
    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:497)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
    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:497)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
    at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl.run(DefaultExecutorFactory.java:64)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountRepository': Invocation of init method failed; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:736)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    ... 44 more
Caused by: java.lang.NullPointerException
    at org.springframework.data.neo4j.mapping.Neo4jPersistentProperty.<init>(Neo4jPersistentProperty.java:72)
    at org.springframework.data.neo4j.mapping.Neo4jMappingContext.createPersistentProperty(Neo4jMappingContext.java:105)
    at org.springframework.data.neo4j.mapping.Neo4jMappingContext.createPersistentProperty(Neo4jMappingContext.java:41)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:468)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:446)
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:605)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:314)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:489)
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:446)
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:605)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:314)
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:276)
    at org.springframework.data.neo4j.mapping.Neo4jMappingContext.<init>(Neo4jMappingContext.java:64)
    at org.springframework.data.neo4j.repository.support.GraphRepositoryFactoryBean.afterPropertiesSet(GraphRepositoryFactoryBean.java:41)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 59 more

我找了又找,还是找不到解决办法。堆栈跟踪对于确定为什么 this 应该为 null 毫无用处。

@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan(basePackages = {"co.foo.data"})
@ContextConfiguration(classes={Neo4jTestConfiguration.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class AccountRepositoryTest {
    @Autowired
    AccountRepository accountRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Test
    public void testCreateAccount() {
        Account account = new Account(new Institution("TestBank"));
        accountRepository.save(account);
        assertNotNull(account.getNodeId());
        assertEquals(account.getInstitution().name, "TestBank");
    }

    @Test
    public void testTransactionsForAccount() {
        Account account = new Account(new Institution("TestBank"));
        accountRepository.save(account);
        assertNotNull(account.getNodeId());
        User user = new User("testuser", "Test", "User", "testpass", null, passwordEncoder, User.Roles.ROLE_USER);
        user.addAccount(account);
        Transaction transaction = new Transaction();
        transaction.Description = "Coffee";
        transaction.Amount = new BigDecimal("3.45");
        transaction.TransactionDate = ZonedDateTime.parse("2015-06-09T16:15:30+01:00[Europe/London]");
        account.addTransaction(transaction);
        userRepository.save(user);

        // Now retrieve
        assertEquals(1, userRepository.count());
        User testuser = userRepository.findOne(user.getNodeId());
        assertEquals(1, testuser.getAccounts().size());
        Account testuser_account = (Account)testuser.getAccounts().toArray()[0];
        assertEquals(1, testuser_account.getTransactions().size());
    }
}

存储库

public interface AccountRepository extends GraphRepository<Account> {
}

public interface UserRepository extends GraphRepository<User> {
    User findByUsername(String username);
}

build.gradle

group 'co.foo.data'
version '1.0.SNAPSHOT'

def neo4jVersion = "2.1.8"
def springVersion = '4.1.6.RELEASE'
def springSecurityVersion = '4.0.0.RC1'
def springDataNeo4jVersion = '4.0.0.BUILD-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'maven'
apply plugin: 'ivy-publish'

sourceCompatibility = 1.7
targetCompatibility = 1.7


repositories {
    mavenCentral()
    maven { url "https://m2.neo4j.org/content/repositories/releases" }
    maven { url "https://m2.neo4j.org/content/repositories/snapshots" }
    maven { url "https://repo.spring.io/libs-release" }
    maven { url "https://repo.spring.io/libs-snapshot" }
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}

dependencies {
    compile "org.springframework.data:spring-data-neo4j:$springDataNeo4jVersion"

    // Neo4j
    compile "org.neo4j.app:neo4j-server:$neo4jVersion"
    compile "org.springframework.security:spring-security-config:$springSecurityVersion"
    compile "javax.inject:javax.inject:1"

    // Tests
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile "org.springframework:spring-test:$springVersion"
    testCompile group: 'org.neo4j', name: 'neo4j-kernel', version: '$neo4jVersion', classifier: 'tests'
    testCompile group: 'org.neo4j.app', name: 'neo4j-server', version: '$neo4jVersion', classifier: 'tests'

}

我什至尝试关注这个项目https://github.com/neo4j-examples/neo4j-ogm-university,但即使那样也无法构建。我会以错误的方式解决这个问题吗?当然,这么简单的事情不应该花费我数周的时间,而我似乎为此浪费了数周的时间。

Neo4jTestConfiguration

@Configuration
@EnableNeo4jRepositories(basePackages = "co.foo.data.repositories")
@EnableTransactionManagement
@ComponentScan("co.foo.data")
public class Neo4jTestConfiguration extends Neo4jConfiguration {
    @Override
    public SessionFactory getSessionFactory() {
        return new SessionFactory("co.foo.data");
    }

    @Bean
    @Override
    public Neo4jServer neo4jServer() {
        return new RemoteServer("http://localhost:7575");
    }

    @Override
    @Bean
    public Session getSession() throws Exception {
        return super.getSession();
    }
}

InProcessServer 仍然可用。请参阅 ,其中列出了在使用 RC1 或快照构建时要添加的其他依赖项。