Пакет Spring Neo4j поверх REST

Я использую Neo4j в автономном режиме с Spring Data for Neo4j в своем приложении. Мой код должен быть в состоянии гарантировать, что при попытке сохранить объект либо все вводится, либо ничего не происходит. Я знаю, что транзакции не поддерживаются через REST в Spring Neo4j, но пакетная операция в REST API Neo4j должна подойти для моих текущих нужд. Операций не так много, но весь вызов save() должен быть по принципу «все или ничего».

Однако похоже, что Spring не делает этого по умолчанию. Если во время записи возникает исключение RuntimeException, в базу данных все равно будут помещены некоторые частичные данные. Я хотел бы продолжать использовать интерфейс GraphRepository, но если это невозможно, я полагаю, что мог бы реализовать это вручную.

Вот некоторый упрощенный пример кода, чтобы проиллюстрировать, что происходит

ПОЖО:

@NodeEntity
public class TestObject {
  @GraphId
  private Long id;
  private String name;

  @Fetch
  @RelatedTo(type = "SIBLING_OF", direction = Direction.BOTH)
  private Set<TestObject> siblings;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    if (name == "fail") {
      throw new RuntimeException();
    }
    return name;
  }

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

  public Set<TestObject> getSiblings() {
    return siblings;
  }

  public void setSiblings(Set<TestObject> siblings) {
    this.siblings = siblings;
  }
}

Репозиторий

public interface TestRepository extends GraphRepository<TestObject>{}

Тест

public class Test {
  @Autowired
  TestRepository repo;

  public void run() {
    final TestObject o1 = new TestObject();
    o1.setName("good1");

    final TestObject o2 = new TestObject();
    o1.setName("good2");

    final TestObject o3 = new TestObject();
    o1.setName("good3");

    final TestObject o4 = new TestObject();
    o1.setName("fail");

    o1.setSiblings(new HashSet<TestObject>() {{
      add(o2);
      add(o3);
      add(o4);
    }});

    //throws exception, but o1 node is created in Neo4j
    repo.save(o1);
  }

  public static void main(String[] args) {
    ApplicationContext appContext = new ClassPathXmlApplicationContext("context.xml");
    Test t = (Test) appContext.getBean("test");
    t.run();
  }
}

person monitorjbl    schedule 01.02.2014    source источник


Ответы (1)


SDN на самом деле не поддерживает «поддельные» транзакции, которые пакетный API представляет по сети, поскольку он использует чтение после записи, и это не работает.

На данный момент я бы предпочел либо запустить SDN со встроенной БД, либо написать расширение сервера с использованием SDN и открыть пользовательскую конечную точку REST.

person Michael Hunger    schedule 02.02.2014
comment
Я бы предпочел не идти по встроенному маршруту. У вас есть ссылка на некоторые примеры серверных расширений в SDN? - person monitorjbl; 03.02.2014
comment
В качестве альтернативы, есть ли способ повторно использовать код, который SDN использует для создания узла JSON из POJO? Я мог бы довольно легко реализовать свой собственный метод saveInBatch(), используя ванильный REST API, если бы я мог воспользоваться преимуществами того, что уже делает SDN. - person monitorjbl; 04.02.2014