cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Having a relationship in an entity constructor

paulB
Node Clone

Hello,

I read the documentation but did not find any precision on this question :
Is it possible to have a related entity only in constructor (no setter defined)?

I have this use case where an entity (a:A) has no business logic if it is not related to another one (b:B) (one and not a list of (B)).
So in java I define this by putting a final field b (B) in (A) definition.
This field is set at construction, and (B) entity is pass to the constructor of (A).
My firsts tests failed. Is that Spring Data Neo4j compatible?

Thank you for reading and any effort you put into helping will be appreciate.

1 ACCEPTED SOLUTION

gerrit_meier
Neo4j
Neo4j

This is definitely possible with SDN.

class A {
  @Relationship("KNOWS")
  private final B b;

  A(B b) {
    this.b = b;
  }
}

Test sources in SDN (randomly picked with List instead of scalar value):
Entity: spring-data-neo4j/ImmutablePerson.java at 78bb07356bd6d646bbc08ad1adcb1509c51ab655 · spring-projects...

Test: spring-data-neo4j/RepositoryIT.java at 78bb07356bd6d646bbc08ad1adcb1509c51ab655 · spring-projects/sp...

View solution in original post

5 REPLIES 5

gerrit_meier
Neo4j
Neo4j

This is definitely possible with SDN.

class A {
  @Relationship("KNOWS")
  private final B b;

  A(B b) {
    this.b = b;
  }
}

Test sources in SDN (randomly picked with List instead of scalar value):
Entity: spring-data-neo4j/ImmutablePerson.java at 78bb07356bd6d646bbc08ad1adcb1509c51ab655 · spring-projects...

Test: spring-data-neo4j/RepositoryIT.java at 78bb07356bd6d646bbc08ad1adcb1509c51ab655 · spring-projects/sp...

Thank you for pointing this out.

I don't know if such example is put somewhere in the documentation.
If there is, I didn't find it and I'm sorry for the inconvenience.

Again thank you for your quick help,
have a nice day.

You're welcome. I couldn't find any example either (and I partially have written this) but I personally do not think it is missing, because it should not be an exception and enforce you to do something special.
I am also writing this reply to give you the hint that, maybe obvious, maybe not obvious, a constellation like:

class A {
A(B b) {}
}
class B {
B(A a) {}
}

would not work if they are referring to the same nodes. SDN will throw an exception in this case because A is still in creation while B requests the very same A.

paulB
Node Clone

@gerrit.meier
Sorry for sending a new message on this question, but I still have a problem.
I'm not sure that the test you point out is complete as it doesn't verify that returned entity are connected (i.e. wasOnboardedBy is not empty).

In my case I have, in my entity constructor, a check for related entity to not be null.
And tests actually failed because the related entity is null.
That is with a simple query that return something as describe here.
So :

+-----------------------------------------------------------------------------------------+
| m               | relations                            | nodes                          |
+-----------------------------------------------------------------------------------------+
| (rootNode:Type) | [[:REL_TYPE], [:OTHER_REL_TYPE], ...]| [(:aType), (:anotherType),...] |
+-----------------------------------------------------------------------------------------+

Relations are only from or to the root entity and nodes are the other end of the relations.

Given the linked test, I have added the last line to check.

ImmutablePerson p1 //..
ImmutablePerson p3 //..
ImmutablePerson p4 = new ImmutablePerson("Person4", Arrays.asList(p1, p3));
// .. save and load people
assertThat(people.stream().filter(p -> p.getName().equals("Person4"))
		.findFirst().get().getWasOnboardedBy()).hasSize(2);

Have you checked names of relationships and the correct node labels?
I think to get to the root of your problem, it might be helpful to get a small reproducer.