当前位置: 首页 > 知识库问答 >
问题:

无法将两个Neo4j实例与Spring Boot/Spring数据Neo4j一起使用

斜浩穰
2023-03-14

预期行为

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

语境

假设我正在经营一家图书馆,并将书籍出租给其他用户。如果用户从我这里租用书籍,那么他们的存储库中将显示相同的节点详细信息,我将允许他们通过我的应用程序编辑节点实体(如添加关键字、添加书籍的亮点等)

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

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

我的Neo4j存储库详细信息

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

租用用户的Neo4j存储库详细信息(通过在其他机器上运行的超文本传输协议访问)

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());
}
}

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

**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中的节点实体名称。我的图书馆。实体:账簿

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

请让我知道为什么在使用Neo4j存储库时会出现此问题?我们不能将两个Neo4j存储库与Spring数据Neo4j一起使用吗

我的环境

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.

共有1个答案

江烨伟
2023-03-14

更新这已经在Spring Data Neo4j Lovelace RC1中得到解决,我们写了一个小方法:https://michael-simons.github.io/neo4j-sdn-ogm-tips/using_multiple_session_factories

感谢您将此作为GitHub第498期提交。

目前的Spring Data Neo4j版本似乎在将不同的会话工厂传播到存储库方面存在缺陷。简而言之:现在没有办法做到这一点(例如,您可以使用Spring数据JPA)。

如果您需要(并且想要)存储库,我现在无法帮助您。然而,工作是注入不同的会话工厂:

    @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);

不管我们的代码中有什么bug,我建议使用以下配置。对于主bean(“myUserconfiguration”),使用一个配置类

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将默认属性映射到neo4jproperty实例(我们的properties类),并像创建动作配置一样使用它。

对于另一个会话工厂也是如此:

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());
    }
}

在这里,您可以映射所有以租赁为前缀的房产。数据neo4j到另一个属性实例。

 类似资料:
  • 当我尝试将Spring Data JPA和spring的数据MongoDB与springboot一起使用时,它假设我的Mongo实体也是JPA实体,并抛出错误。 我有Person JPA实体和扩展了JPARepository的PersonRepository。并且我有用户Mongo实体和扩展MongoRepository的UserRepository。 当我启动应用程序时,我会得到以下错误: 这方

  • 我正在使用SDN和嵌入式neo4j。我必须使用bean验证,但它不起作用。null正在数据库中保存,没有任何异常。 依赖是 实体类 控制器是 我使用的是sping-data-neo4j 3.2.0。发布

  • 我开始使用Neo4j和Spring Data Neo4j的项目。我希望我的程序使用已经包含我的数据的本地数据库(而不是每次启动时加载数据),因为我有很多数据需要加载到数据库中。为了实现这个目标,我尝试设置一个用我的数据填充数据库的测试用例。但是,在我的测试完成后,数据库中的数据似乎不会持久:我使用neo4j控制台/shell查看数据库,发现它是空的。 我已经构建了一个小的例子项目,也不工作。任何对

  • 我试图将属性存储为Neo4j图中的节点,然后可以使用Spring Data Rest API访问这些节点。(然后我想在我的图中找到具有相同属性的对象。)我的对象的JSON表示应该像 最简单的方法是 显然,这不起作用,就像地图一样。条目不是@NodeEntity。 有没有简单的方法来实现这一点?

  • 我在windows机器上运行的ubuntu命令行上安装了community 4.1.1 neo4j服务。我已经稳定地使用neo4j一两个月了,就在最近它阻止了我访问neo4j数据库,它会在neo4j浏览器中这样说: 如果我运行。/neo4j-community-4.1.1/bin/cypher-shell-a192.168.0.19,它表示:

  • Neo4j 2.0。0已发布。所以我更新了neo4j版本2.0。0.M6到2.0。0.0发布。并尝试在我的网站中更新模型,但出现异常。 组织。springframework。刀。DataIntegrityViolationException:唯一属性类java。lang.String rankStatId rel:false idx:true被设置为重复值3073631_99 MY SDN版本是2