无法将两个Neo4j实例与Spring Boot/Spring数据Neo4j一起使用 [英] Unable to use two Neo4j Instances with Spring boot/Spring data neo4j

查看:166
本文介绍了无法将两个Neo4j实例与Spring Boot/Spring数据Neo4j一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

预期行为

Trying to use two Neo4j instances with Spring boot and Spring data Neo4j

当前行为

Able to use only one Neo4j instances. Unable to use two repositories.

复制步骤(针对错误)

1. Run two Neo4j Instances
2. Create Data source configuration for both Neo4j Instances using spring boot.
3. Use Repository to access the Node entity
4. It will throw error

上下文

请考虑我正在管理一个图书馆并将书租给其他用户.如果用户要从我这里租书,则相同的节点详细信息将出现在他们的存储库中,我将允许他们通过我的应用程序编辑节点实体(例如添加关键字,添加有关书籍的重点信息等)

Consider that I am running a library and renting books to other users. If the user is renting the book from me, the same node details will be present in their repository and I will allow them to edit the node entity through my application (like adding keywords, adding highlights about the books etc.)

因此,在两个存储库中,节点详细信息都是相同的.

So in both repository the node details will be same.

以下是应用程序.两个Neo4j存储库的属性详细信息.

Below are the application. properties details for both Neo4j repositories.

我的Neo4j存储库详细信息

spring.data.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=neo4j

出租用户的Neo4j存储库详细信息 (通过在其他计算机上运行的http访问)

Rental User's Neo4j Repository Details (Accessing through http which is running in some other machine)

rental.data.neo4j.uri=bolt://...:7687
rental.data.neo4j.username=neo4j
rental.data.neo4j.password=neo4j

以下是租借用户"的Neo4j配置:

@configuration
@EnableNeo4jRepositories(basePackages = "com.metadata.dao.rentallibrary", sessionFactoryRef = "rentalSessionFactory", transactionManagerRef = "rentalUsertransactionManager")
@EnableTransactionManagement
@EntityScan("com.metadata.dao")
public class rentalUserNeo4jConfiguration {

@Value("${rental.data.neo4j.uri}")
private String url;

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

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

@Bean(name = "rentalSessionFactory")
public SessionFactory rentalUserSessionFactory() {
    return new SessionFactory(rentalNeo4jconfiguration(), "com.metadata.dao.rentallibrary.entity");
}

@Bean
public org.neo4j.ogm.config.Configuration rentalNeo4jconfiguration() {
    org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder().uri(url)// "
            .credentials(userName, password)
            .build();
    return configuration;
}

@Bean
public Neo4jTransactionManager rentalUsertransactionManager() {
    return new Neo4jTransactionManager(rentalUserSessionFactory());
}
}

以下是我的图书馆的Neo4j配置详细信息:

@configuration
@EnableNeo4jRepositories(basePackages = "com.metadata.dao.mylibrary", sessionFactoryRef = "myUserSessionFactory", transactionManagerRef = "myUserTransactionManager")
@EnableTransactionManagement
public class MyUserNeo4jConfiguration {

@Value("${spring.data.neo4j.uri}")
private String url;

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

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

@Bean(name = "myUserSessionFactory")
@Primary
public SessionFactory myUserSessionFactory() {
    return new SessionFactory(myUserconfiguration(), "com.metadata.dao.mylibrary.entity");
}

@Bean
public org.neo4j.ogm.config.Configuration myUserconfiguration() {
    org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder().uri(url)
            .credentials(userName, password)
            .build();
    return configuration;
}

@Bean
public Neo4jTransactionManager myUserTransactionManager() {
    return new Neo4jTransactionManager(myUserSessionFactory());
}
}

我正在尝试使用会话工厂(通过限定符)访问两个存储库,但工作正常.但是我正试图通过面临问题的存储库来访问数据.

I am trying access both repositories using session Factory (via qualifier) it is working fine. But I am trying to access the data, through repositories I am facing the Issue.

**Accessing through SessionFactory :**

@Autowired
@Qualifier(value = "myUserSessionFactory")
SessionFactory myUserSessionFactory;

@Autowired
@Qualifier(value = "rentalUserSessionFactory")
SessionFactory rentalUserSessionFactory;

以下是错误详细信息,当我尝试通过:

java.lang.IllegalArgumentException: Class class com.metadata.dao.Book is not a valid entity class. Please check the entity mapping.
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:88) ~[neo4j-ogm-core-3.1.0.jar:3.1.0]
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:40) ~[neo4j-ogm-core-3.1.0.jar:3.1.0]
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:469) ~[neo4j-ogm-core-3.1.0.jar:3.1.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_141]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_141]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_141]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_141]
at org.springframework.data.neo4j.transaction.SharedSessionCreator$SharedSessionInvocationHandler.invoke(SharedSessionCreator.java:131) ~[spring-data-neo4j-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at com.sun.proxy.$Proxy81.save(Unknown Source) ~[na:na]

org.neo4j.ogm.exception.core.TransactionManagerException: Transaction is not current for this thread
at org.neo4j.ogm.session.transaction.DefaultTransactionManager.rollback(DefaultTransactionManager.java:86) ~[neo4j-ogm-core-3.1.0.jar:3.1.0]
at org.neo4j.ogm.transaction.AbstractTransaction.rollback(AbstractTransaction.java:65) ~[neo4j-ogm-api-3.1.0.jar:3.1.0]
at org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction.rollback(BoltTransaction.java:61) ~[neo4j-ogm-bolt-driver-3.1.0.jar:3.1.0]
at org.neo4j.ogm.transaction.AbstractTransaction.close(AbstractTransaction.java:144) ~[neo4j-ogm-api-3.1.0.jar:3.1.0]
at org.springframework.data.neo4j.transaction.Neo4jTransactionManager.doCleanupAfterCompletion(Neo4jTransactionManager.java:379) ~[spring-data-neo4j-5.0.8.RELEASE.jar:5.0.8.RELEASE]

dao.mylibrary.entity中的节点实体名称:Book

Node Entity Name in dao.mylibrary.entity : Book

dao.rentallibrary.entity中的节点实体名称:RentedBook

Node Entity Name in dao.rentallibrary.entity : RentedBook

请让我知道为什么在使用Neo4j存储库时出现此问题?我们不能将两个Neo4j存储库与Spring数据neo4j&春季靴?还是我做错了什么?

Please let me know why this issue is occurring while using Neo4j repositories? Can't we use two Neo4j repositories with Spring data neo4j & Spring boot? Or Am I doing something wrong?

我的环境

OGM Version used: 3.1.0
Java Version used: 1.8
Neo4J Version used:3.2.3
Bolt Driver Version used (if applicable): 3.1.0
Operating System and Version: Windows
Please let me know if you need any additional information.

推荐答案

更新此问题已在Spring Data Neo4j Lovelace RC1中得到解决,我们编写了一个小方法:

Update This has been addressed in Spring Data Neo4j Lovelace RC1 and we wrote a small howto: https://michael-simons.github.io/neo4j-sdn-ogm-tips/using_multiple_session_factories

感谢将此作为GitHub问题#498 提交.

Thanks for submitting this as GitHub issue #498.

看来,当前的Spring Data Neo4j版本在将不同的会话工厂传播到存储库方面有一个错误.简而言之:目前尚无办法进行这项工作(例如,像使用Spring Data JPA一样).

It seems that the current Spring Data Neo4j version has a bug in propagating the different session factories to the repositories. In short: there is no way to make this work right now (for example like you can do with Spring Data JPA).

如果您需要(并且想要)存储库,那么我现在无法为您提供帮助.但是,什么工作正在注入不同的会话工厂:

If you need (and want) repositories, I cannot help you right now. What work's however is injecting the different session factories:

    @Autowired
    @Qualifier("myUserSessionFactory")
    private SessionFactory myUserSessionFactory;

    @Autowired
    @Qualifier("rentalUserSessionFactory")
    private SessionFactory rentalUserSessionFactory;

然后做类似的事情

Map<String, Object> params = new HashMap<>();
params.put("name", "test");
ThingEntity t = this.myUserSessionFactory.openSession().queryForObject(
                ThingEntity.class,
                "MATCH (n:`Thing`) WHERE n.name = $name WITH n RETURN n", params);

不管我们代码中的错误是什么,我都建议使用以下配置.对于主bean("myUserconfiguration"),请使用一个配置类

Regardless of the bug in our code, I recommend the following configuration. For the primary beans ("myUserconfiguration") use one config class

package gh.neo4jogm.gh498;

import gh.neo4jogm.gh498.domain1.ThingEntity;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.boot.autoconfigure.data.neo4j.Neo4jProperties;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;

@Configuration
@EnableNeo4jRepositories(
    basePackages = Domain1Config.BASE_PACKAGE,
    sessionFactoryRef = "myUserSessionFactory",
    transactionManagerRef = "myUserTransactionManager"
)
@EntityScan(basePackageClasses = ThingEntity.class)
class Domain1Config {

    static final String BASE_PACKAGE = "gh.neo4jogm.gh498.domain1";

    @Primary
    @Bean
    @ConfigurationProperties("spring.data.neo4j")
    public Neo4jProperties myNeo4jProperties() {
        return new Neo4jProperties();
    }

    @Primary
    @Bean
    public org.neo4j.ogm.config.Configuration myUserconfiguration() {
        return myNeo4jProperties().createConfiguration();
    }

    @Primary
    @Bean
    public SessionFactory myUserSessionFactory() {
        return new SessionFactory(myUserconfiguration(), BASE_PACKAGE);
    }

    @Bean
    public Neo4jTransactionManager myUserTransactionManager() {
        return new Neo4jTransactionManager(myUserSessionFactory());
    }
}

基本思想是使用@ConfigurationProperties将默认属性映射到Neo4jProperties(我们的属性类)的实例,并像创建动作配置一样使用它.

The basic idea is to use @ConfigurationProperties to map the default properties to an instance of Neo4jProperties (our properties class) and use it like we do create the action configuration.

与其他会话工厂相同:

package gh.neo4jogm.gh498;

import gh.neo4jogm.gh498.domain2.OtherThingEntity;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.boot.autoconfigure.data.neo4j.Neo4jProperties;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;

import static gh.neo4jogm.gh498.Domain2Config.BASE_PACKAGE;

@Configuration
@EnableNeo4jRepositories(
    basePackages = BASE_PACKAGE,
    sessionFactoryRef = "rentalUserSessionFactory",
    transactionManagerRef = "rentalUsertransactionManager"
)
@EntityScan(basePackageClasses = OtherThingEntity.class)
class Domain2Config {

    static final String BASE_PACKAGE = "gh.neo4jogm.gh498.domain2";

    @Bean
    @ConfigurationProperties("rental.data.neo4j")
    public Neo4jProperties rentalNeo4jProperties() {
        return new Neo4jProperties();
    }

    @Bean
    public org.neo4j.ogm.config.Configuration rentalNeo4jconfiguration() {
        return rentalNeo4jProperties().createConfiguration();
    }

    @Bean
    public SessionFactory rentalUserSessionFactory() {
        return new SessionFactory(rentalNeo4jconfiguration(), BASE_PACKAGE);
    }

    @Bean
    public Neo4jTransactionManager rentalUsertransactionManager() {
        return new Neo4jTransactionManager(rentalUserSessionFactory());
    }
}

在这里,您将所有以rental.data.neo4j为前缀的属性映射到另一个属性实例.

Here you map all properties prefixed with rental.data.neo4j to another properties instance.

这篇关于无法将两个Neo4j实例与Spring Boot/Spring数据Neo4j一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆