1

Мы используем версию 4.2.0M1 (в настоящее время последнюю) Spring Data Neo4j, и перед нами возникает проблема, когда мы пытаемся удалить связанный дочерний узел из родительский сбор, а затем сохранить через родительский репозиторий.Spring Data Neo4j (4.2.0.M1) Ошибка связи между узлами

МОДЕЛЬ КЛАССЫ:

@NodeEntity 
public class Movie { 

    @GraphId 
    private Long graphId; 

    private String name; 

    /** 
    * @return the graphId 
    */ 
    public Long getGraphId() { 
     return graphId; 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

@NodeEntity 
public class Actor { 

    @GraphId 
    private Long graphId; 

    private String name; 

    @Relationship(type = "ACTS_IN") 
    private Set<Movie> movies = new HashSet<>(); 

    /** 
    * @return the graphId 
    */ 
    public Long getGraphId() { 
     return graphId; 
    } 

    /** 
    * @return the movies 
    */ 
    public Set<Movie> getMovies() { 
     return movies; 
    } 

    public void addMovie(Movie movie) { 
     movies.add(movie); 
    } 

    public void removeMovie(Movie movie) { 
     movies.remove(movie); 
    } 

    /** 
    * @param movies the movies to set 
    */ 
    public void setMovies(Set<Movie> movies) { 
     this.movies = movies; 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(String name) { 
     this.name = name; 
    } 

} 

ТЕСТ КЛАСС:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={RelationAndCacheTest.TestConfiguration.class}) 
@DirtiesContext(classMode = ClassMode.AFTER_CLASS) 
public class RelationAndCacheTest { 


@Autowired 
private ActorRepository actorRepository; 

private static Session neo4jSession; 

@Configuration 
@EnableAutoConfiguration 
@EnableTransactionManagement 
@EnableExperimentalNeo4jRepositories("com.xxx") 
public static class TestConfiguration { 

    @Bean 
    public org.neo4j.ogm.config.Configuration configuration() { 
     org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); 
     config 
     .driverConfiguration() 
     .setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver").setURI("http://localhost:7474"); 
      return config; 
     } 

     @Bean 
     public SessionFactory sessionFactory() { 
      return new SessionFactory(configuration(), "com.xxx") { 
       @Override 
       public Session openSession() { 
        neo4jSession = super.openSession(); 
        return neo4jSession; 
       } 
      }; 
     } 

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

    } 

    @Test 
    public void relationModificationTest() { 

     /** Create an actor named Roger and save it => working */ 
     Actor actor = new Actor(); 
     actor.setName("Roger"); 
     actor = actorRepository.save(actor); 

     /** Create a movie and link it to the actor by saving it through the actor repository => working */ 
     Movie movie = new Movie(); 
     movie.setName("movie"); 
     actor.addMovie(movie); 
     actor = actorRepository.save(actor); 

     /** Remove the movie from the actor and save through the actor repository => link not removed !! */ 
     actor.removeMovie((Movie) actor.getMovies().toArray()[0]); 
     actor.setName("bob"); 
     actor = actorRepository.save(actor); 
    } 

} 

Ссылка не должна быть удалена? это ошибка? Кто-нибудь сталкивается с той же проблемой?

+0

Ваш код выглядит хорошо для меня.То, что вы пытаетесь, должно быть покрыто базовым набором тестов, который должен пройти до того, как будет загружена сборка M1 или SNAPSHOT. Можете ли вы отправить неудачный код на [email protected]? –

+0

Да, он отправлен, я пропустил небольшой тестовый проект. Держите меня здесь в своих расследованиях. С уважением. – Oizo

ответ

2

TL; DR

Есть два решения проблемы:

1) аннотировать метод испытания @Transactional

2) извлечение объектов каждый раз, когда перед какими-либо операциями, которые мутируют их ,

Полное объяснение

Существует важное различие между поведением SDN 4.1 и 4.2 SDN в отношении основного объекта OGM Session.

Основная роль объекта Session заключается в том, чтобы отслеживать, что вы делаете, чтобы он мог определять, какие операции выполнять на графике, когда вы сохраняете объект. По сути, это кеш, который отслеживает состояние ваших объектов, когда вы проходите цикл загрузки, обновления и сохранения.

В SDN 4.1 сессия не была привязана к жизненному циклу транзакции Spring. Была создана сессия за пределами, а транзакционный контекст и область сеанса (время жизни) управлялись путем аннотации его аннотацией @Scope или программным запросом нового сеанса, когда это необходимо.

В 4.2 время жизни сеанса было изменено на привязку к контексту транзакции Spring, в котором происходит операция репозитория, которая, в свою очередь, связана с потоком, выполняющим запрос. Чтобы это всегда срабатывало, новая транзакция должна быть создана для вас, если вы еще не в полете. Каждая новая транзакция теперь получит новый объект Session.

Итак, причина, по которой этот код работал в 4.1, а не в 4.2, заключается в том, что больше не существует общего сеанса между вызовами в ActorRepository. Информация сеанса от первого вызова репозитория недоступна для второго (включая критически, какие отношения являются новыми и которые в настоящее время сохраняются на графике), поскольку они участвуют в отдельных транзакциях.

Поведение 4.2 было изменено, поскольку 4.1 вынудило несколько ограничений на способность приложений SDN полностью интегрироваться с платформой Spring.

Пожалуйста, смотрите http://graphaware.com/neo4j/2016/09/30/upgrading-to-sdn-42.html для получения дополнительной информации, в том числе шаги предпринять для того, чтобы модернизировать от SDN 4.1 до 4.2

+0

спасибо, теперь понятно. – Oizo

Смежные вопросы