Reputation: 5277
I have the following entities:
@NodeEntity(label = "A")
public class A {
@Property(name = "something")
private String someProperty;
//... getters and setters
}
@NodeEntity(label = "B")
public class B {
@Property(name = "someOtherThing")
private String otherProperty;
//... getters and setters
}
@RelationshipEntity(type = "AB")
public class AB {
@StartNode
private A start;
@EndNode
private B end;
@Property(name = "evenOtherThing")
private String prop;
//... getters and setters
}
So, in this situation I have (:A)-[:AB]->(:B)
. I can have several AB
s (meaning I can connect A to B several times, having different properties each time).
With that configuration I can save AB instances without problems, but when it comes to deleting just the relationship, I couldn't find a way to do so, using the spring-data-neo4j methods.
Things that I tried:
1- Custom query:
@Repository
public interface ABRepository extends GraphRepository<AB> {
@Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} DELETE ab")
void deleteBySomething(@Param("something") String something);
}
Usage:
@Autowired
ABRepository repository;
//...
repository.deleteBySomething(something);
It didn't work as expected. The A node is removed altogether with the AB relationship. If I run the query directly at the database, it works as expected.
2- Delete from the repository:
@Repository
public interface ABRepository extends GraphRepository<AB> {
@Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} RETURN a,ab,b")
Iterable<AB> findBySomething(@Param("something") String something);
}
Usage:
Iterable<AB> it = repository.findBySomething(something);
repository.delete(it);
Same stuff. The nodes are removed. I tried to iterate over the Iterable<AB>
and remove the relationships one by one, without success as well.
3- Nulling the references of A and B inside AB and saving AB:
Same code of the repository, with a different usage:
Iterable<AB> it = repository.findBySomething(something);
for (AB ab : it) {
ab.setA(null);
ab.setB(null);
}
repository.save(it);
Here I'm just trying random stuff. It didn't work as expected. The framework rises an exception stating that the start and end nodes can't be null.
So, what am I doing wrong? What does it take to remove a simple relationship from the database using spring-data-neo4j, without removing the linking nodes?
For the record: my neo4j database is v.3.0.4 and my spring-data-neo4j is v.4.1.4.RELEASE. Running Java 8.
Upvotes: 0
Views: 603
Reputation: 5277
In the end the problem was a sum of two factors.
First: not mentioned in the question, but the way I saved the AB entity wasn't ideal. I was using repository.save(ab)
directly, and that can make the framework do some magic with the A and B entities inside. To save just the relationship, without touching the related entities, the repository.save(ab, 0)
should be used.
Second: removing entities using a custom query is intuitively faster than fetching the entities and then removing them, so using that approach was my first goal. And here again I was confused by some magic behind the scenes, better described at this question: Spring Data Neo4j 4returning cached results?
In summary, after removing entities or relationships using custom queries, I should clear the session:
@Autowired
Session session;
//...
repository.deleteBySomething(something);
session.clear();
These two tweaks fixed the weird behavior I was having with the framework.
Upvotes: 2