Невозможно использовать два экземпляра Neo4j с загрузочными данными Spring / Spring neo4j - PullRequest
0 голосов
/ 03 июля 2018

Ожидаемое поведение

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

Context

Учтите, что я управляю библиотекой и сдаю книги другим пользователям. Если пользователь арендует книгу у меня, в его репозитории будут присутствовать те же сведения об узле, и я позволю им редактировать сущность узла через мое приложение (например, добавление ключевых слов, добавление основных моментов о книгах и т. Д.)

Таким образом, в обоих хранилищах данные узла будут одинаковыми.

Ниже приведены заявки. подробная информация о свойствах обоих репозиториев Neo4j.

My Neo4j Repository Details

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

Сведения об аренде Neo4j пользователя (Доступ через http, который работает на другом компьютере)

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

Я пытаюсь получить доступ к обоим репозиториям с помощью Factory Factory (через квалификатор), он работает нормально Но я пытаюсь получить доступ к данным через репозитории, с которыми сталкиваюсь.

**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

Имя сущности узла в dao.rentallibrary.entity: RentedBook

Пожалуйста, дайте мне знать, почему эта проблема возникает при использовании репозиториев Neo4j? Разве мы не можем использовать два репозитория Neo4j с Spring data neo4j и Spring boot? Или я что-то не так делаю?

Мое окружение

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 Ответ

0 голосов
/ 04 июля 2018

Обновление Эта проблема была решена в Spring Data Neo4j Lovelace RC1, и мы написали небольшое руководство: https://michael -simons.github.io / neo4j-sdn-ogm-tips / using_multiple_session_factories

Спасибо за сообщение об этом как о выпуске GitHub # 498 .

Похоже, что в текущей версии Spring Data Neo4j есть ошибка при распространении различных фабрик сессий в репозитории. Короче говоря, сейчас нет способа заставить это работать (например, как вы можете сделать с Spring Data 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);

Независимо от ошибки в нашем коде, я рекомендую следующую конфигурацию. Для основных компонентов («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 для сопоставления свойств по умолчанию с экземпляром Neo4jProperties (наш класс свойств) и использовать его так же, как мы создаем конфигурацию действия.

То же самое для другой фабрики сеансов:

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 другому экземпляру свойств.

...