SDN4 Java 配置和 indexes.auto=assert

SDN4 Java configuration and indexes.auto=assert

我已将我的 Neo4j 配置从 ogm.properties 移动到 Java 配置。

这是我当前的配置:

@Configuration
@EnableNeo4jRepositories(basePackages = "com.example.domain.repository.neo4j")
@EnableTransactionManagement
public class Neo4jTestConfig {

    @Value("${neo4j.embedded.database.path}")
    private String storeDir;

    @Bean
    public Neo4jTransactionManager transactionManager() throws Exception {
        return new Neo4jTransactionManager(sessionFactory());
    }

    @Bean
    public SessionFactory sessionFactory() {

        Components.setDriver(new EmbeddedDriver(graphDatabaseService()));

        return new SessionFactory("com.example");
    }

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {

        // @formatter:off
        GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory()
                .newEmbeddedDatabaseBuilder(new File(storeDir))
                .loadPropertiesFromFile(this.getClass().getClassLoader().getResource("neo4j.properties").getPath())
                .newGraphDatabase();
        // @formatter:on

        return graphDatabaseService;
    }

}

现在我不知道如何将 OGM 属性 indexes.auto=assert 正确添加到此配置中。

已更新

我已将我的配置更新如下:

@Profile("test")
@Configuration
@EnableNeo4jRepositories(basePackages = "com.example.domain.repository.neo4j")
@EnableTransactionManagement
public class Neo4jTestConfig {

    @Value("${neo4j.embedded.database.path}")
    private String storeDir;

    @Bean
    public Neo4jTransactionManager transactionManager() throws Exception {
        return new Neo4jTransactionManager(sessionFactory());
    }

    @Bean
    public SessionFactory sessionFactory() {

        Components.setDriver(new EmbeddedDriver(graphDatabaseService()));

        return new SessionFactory(configuration(), "com.example.domain.model");
    }

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {

        // @formatter:off
        GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory()
                .newEmbeddedDatabaseBuilder(new File(storeDir))
                .loadPropertiesFromFile(this.getClass().getClassLoader().getResource("neo4j.properties").getPath())
                .newGraphDatabase();
        // @formatter:on

        return graphDatabaseService;
    }

    @Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
        config.autoIndexConfiguration().setAutoIndex("assert");
        return config;
    }

}

但它现在失败了,出现以下异常:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is org.neo4j.ogm.exception.ServiceNotFoundException: Could not load driver: null.
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 80 common frames omitted
Caused by: org.neo4j.ogm.exception.ServiceNotFoundException: Could not load driver: null.
    at org.neo4j.ogm.service.DriverService.load(DriverService.java:57)
    at org.neo4j.ogm.service.DriverService.load(DriverService.java:69)
    at org.neo4j.ogm.service.Components.loadDriver(Components.java:158)
    at org.neo4j.ogm.service.Components.driver(Components.java:104)
    at org.neo4j.ogm.session.SessionFactory.<init>(SessionFactory.java:44)
    at org.neo4j.ogm.session.SessionFactory.<init>(SessionFactory.java:93)
    at com.example.domain.configuration.Neo4jTestConfig.sessionFactory(Neo4jTestConfig.java:37)
    at com.example.domain.configuration.Neo4jTestConfig$$EnhancerBySpringCGLIB$$bde0f39a.CGLIB$sessionFactory(<generated>)
    at com.example.domain.configuration.Neo4jTestConfig$$EnhancerBySpringCGLIB$$bde0f39a$$FastClassBySpringCGLIB$$b12a6805.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
    at com.example.domain.configuration.Neo4jTestConfig$$EnhancerBySpringCGLIB$$bde0f39a.sessionFactory(<generated>)
    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.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 81 common frames omitted

已更新

这是我基于 Bolt Driver 的生产配置:

@Profile("production")
@Configuration
@EnableNeo4jRepositories(basePackages = "com.example.domain.repository.neo4j")
@EnableTransactionManagement
public class Neo4jConfig {

    @Value("${neo4j.server.database.uri}")
    private String serverDatabaseUri;

    @Value("${neo4j.username}")
    private String username;

    @Value("${neo4j.password}")
    private String password;

    @Bean
    public Neo4jTransactionManager transactionManager() throws Exception {
        return new Neo4jTransactionManager(sessionFactory());
    }

    @Bean
    public SessionFactory sessionFactory() {
        Components.setDriver(new BoltDriver());

        return new SessionFactory(configuration(), "com.example.domain.model");
    }

    @Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration();

        // @formatter:off
        configuration
            .autoIndexConfiguration()
                .setAutoIndex("assert");
        configuration
            .driverConfiguration()
                .setCredentials(username, password)
                .setURI(serverDatabaseUri);
        // @formatter:on

        return configuration;
    }

}

此配置工作正常,但基于嵌入式 Java 配置仍然存在问题。

这似乎是 OGM 配置中的一个盲点,因此需要一些技巧。

有 2 个问题:

  • driver class name 必须设置,否则会得到NPE
  • 即使您这样做,您在 Components.setDriver 中设置的驱动程序也会在 new SessionFactory 中被销毁(OGM 认为您正在重新配置它)

对于具有自定义配置的嵌入式数据库,您的 sessionFactory() 应如下所示:

org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration();
// Register your configuration here, this will confuse OGM so the driver you set below won't be destroyed
Components.configure(configuration);

// Register your driver
EmbeddedDriver driver = new EmbeddedDriver(graphDatabaseService());
Components.setDriver(driver);

// Set driver class name so you won't get NPE
configuration.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");

// Configure auto index
configuration.autoIndexConfiguration().setAutoIndex("assert");

return new SessionFactory(configuration, "com.example");

它有效,但请注意它是一个 hack。不过测试应该没问题。