Я использую 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();
}
}