Как сохранить отношения между узлами Neo4J в графе весенних данных без повторного вызова persist

#spring #neo4j #spring-data #spring-data-graph

#spring #neo4j #spring-данные #spring-data-graph

Вопрос:

Приведенный ниже тест завершается неудачей, если я удаляю первый persist(). Почему мне нужно сохранять NodeEntity, чтобы создать экземпляр Set? Есть ли какой-нибудь лучший способ сделать это? Я не хочу выполнять запись в базу данных чаще, чем необходимо.

  @Test
public void testCompetenceCreation() {
    Competence competence = new Competence();
    competence.setName("Testcompetence");
    competence.persist(); //test fails if this line is removed
    Competence competenceFromDb = competenceRepository.findOne(competence.getId());

    assertEquals(competence.getName(), competenceFromDb.getName());

    Education education = new Education();
    education.setName("Bachelors Degree");
    competence.addEducation(education);
    competence.persist();


    assertEquals(competence.getEducations(), competenceFromDb.getEducations());
}
  

Если я удалю указанную строку, произойдет исключение, указанное ниже:

Выдает

 java.lang.NullPointerException
at com.x.entity.Competence.addEducation(Competence.java:54)
  

Competence.class:

 @JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Competence {

    @RelatedTo(type = "EDUCATION", elementClass = Education.class)
    private Set<Education> educations;

    public Set<Education> getEducations() {
        return educations;
    }

    public void addEducation(Education education) {
        this.educations.add(education);
    }
}
  

Education.class

 @JsonIgnoreProperties({"nodeId", "persistentState", "entityState"})
@NodeEntity
public class Education {

    @GraphId
    private Long id;

    @JsonBackReference
    @RelatedTo(type = "COMPETENCE", elementClass = Competence.class, direction = Direction.INCOMING)
    private Competence competence;

    @Indexed
    private String name;

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  

Ответ №1:

Какую версию SDN вы используете?

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

Запись в БД выполняется только при фиксации, поэтому не беспокойтесь о слишком большом количестве записей. Все остальные изменения будут просто сохранены в памяти для вашей транзакции. Вероятно, вам также следует прокомментировать метод тестирования с помощью @Transactional .

Можете ли вы создать проблему с JIRA для этого? Чтобы обеспечить согласованную обработку. (Проблема в том, что он, вероятно, также жалуется, когда вы сами инициализируете набор.)

Две другие вещи:

  • поскольку ваши отношения между Education<—Competence, вероятно, одинаковы и должны просто перемещаться в другом направлении, вы должны указать то же type имя в аннотации.
  • например, Образование<-[:ОБЕСПЕЧИВАЕТ]-Компетентность

  • также, если вы не вызовете persist, ваша сущность не будет создана, а затем findOne, вернув null

Комментарии:

1. Спасибо за ваш быстрый ответ, Майкл. Теперь я понимаю, как мне нужно использовать persist, и вы также были правы в своем замечании о типе отношений в аннотации. Не могли бы вы объяснить, что вы хотите, чтобы я написал в Jira-issue? Поскольку, насколько я понимаю, это не ошибка, а скорее у меня нет полного понимания того, как работает Spring Data Graph 🙂

2. Просто создайте проблему и привяжите ее к этому обсуждению. В качестве описания добавьте — инициализируйте поля коллекции согласованным образом. Спасибо

3. Готово! Еще раз, спасибо за вашу помощь, высоко ценится. jira.springsource.org/browse/DATAGRAPH-135