We've integrated a Spring Boot Application (v2.3.1) with a Neo4j 4.1.0 instance, using SDN/RX project (spring-data-neo4j-rx-spring-boot-starter v1.1.1). The main feature we leverage on is the Dynamic Relationships.
The insert of Nodes and Dynamic Relationships works fine but the following issues/limitations came up:
A) Dynamic relationships are not being populated when retrieving data with a custom "@Query" (see method graphData() below). I tried the same query in Neo4j Browser and works fine. (They're populated ok though, when creating queries from method names find..By() etc.)
B) Defining dynamic relationships via a Map<String, NodeObj> as explained in the documentation, where the key is the relationship type, there can be only 1 Node linked per type. Is this real? why this limitation? any workaround?
How both issues could be solved?
Below is a sample of the code where we face both issues.
Thanks in advance for your help.
Sebastian
@Repository
public interface Neo4jNodeRepository extends Neo4jRepository<Neo4jNode, Long> {
Neo4jNode findByName(String name);
List<Neo4jNode> findByExternalIdIn(Collection<Long> externalIds);
@Query("MATCH (s:Neo4jNode)-[r]-(e:Neo4jNode) WHERE s.externalId = $externalId AND e.externalId = $externalId RETURN s,r,e")
Collection<Neo4jNode> graphData(@Param("externalId") Long externalId);
}
@Node
@Getter
@Setter
public class Neo4jNode {
@Id @GeneratedValue
private Long id;
private String name;
private Long externalId;
@DynamicLabels
private List<String> labels;
private Map<String, Neo4jNode> relationships;
public Neo4jNode() {
this.labels = new ArrayList<String>();
this.relationships = new HashMap<String, Neo4jNode>();
}
public void addLabel(String label) {
if(this.labels == null) {
this.labels = new ArrayList<String>();
}
this.labels.add(label);
}
public void relatesTo(String relationType, Neo4jNode node) {
if (relationships == null) {
relationships = new HashMap<String, Neo4jNode>();
}
relationships.put(relationType, node);
}
}
I am also waiting for solution to this issue. Dynamic Relationships and Relationships with properties, we can save it to database in all the ways which we can achieve using neo4j desktop. But retrievals are not working as we can achieve using neo4j desktop.
You can use a Collection e.g. something like Map<String, List<NodeObj>> for the dynamic relationship to define multiple nodes for the same dynamic relationship type.
A collect(r), collect(e) instead of the scalar return values should do the job, but I have lately also seen an issue around this that might prevent the correct mapping. If there is still a problem, could you raise a ticket for this? Log in - Spring JIRA
Side note: we will update the documentation on relationship with properties in the near future to reflect the current state. For a glance I answered another question how @RelationshipProperties should get defined now Migration to RX - #2 by gerrit.meier
As you have might seen, I just fixed the bug with the custom query mapping for custom queries.
Dynamic relationships should now get mapped correctly.
You can try it out with a build of the main branch, if you want or wait until the GA release that is planned for next week.
Keep in mind that the rule still applies, that you have to use collect... for all other relationships and nodes to emit one row of result for each Neo4jNode.
The latest GA was meant to point towards Spring Data Neo4j 6. That is the official successor of SDN/RX. It got released two weeks ago.
You could wait a little bit longer for the Spring Boot 2.4 release that should take place this week. This will provide the new Spring Data versions.