-
Notifications
You must be signed in to change notification settings - Fork 616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Multi Relationships cannot get right conversion #2973
Comments
I dig into the code, I found in DefaultNeo4jEntityConverter, In So, the Line 435 in f10c95f
Line 317 in f10c95f
I think, it should add few code in Line 440 in f10c95f
add code below can solve this bug: else if (queryResult instanceof Relationship) {
Relationship relationshipRepresentation = (Relationship) queryResult;
labels.add(relationshipRepresentation.type());
} |
I tried to understand the problem and your solution to this with your description and the pull request, but somewhere I lose track. Now when it comes to loading, SDN cannot determine in any way which was the exact class the relationship got constructed with. How should it, given your example? There is just a |
Hi @meistermeier , let's me to explain it For node, the SND can get Node with right types like: @Node
public class BaseNode {
@Id
@GeneratedValue
private UUID id;
}
@Node
public class NodeA extend BaseNode{
String a;
}
@Node
public class NodeB extend BaseNode{
String b;
}
@Repository
public interface BaseNodeRepository extends Neo4jRepository<BaseNode, UUID>,
CypherdslConditionExecutor<BaseNode>,
CypherdslStatementExecutor<BaseNode>,
QuerydslPredicateExecutor<BaseNode> {
}
List<BaseNode> nodes = baseNodeRepository.findAll()
// the nodes may contains NodeA and NodeB, they can get proper class type The nodes may contains NodeA and NodeB, they can get proper class type, The code I think is : Lines 314 to 326 in f10c95f
The I think the relationship has same mechanism, so I write it like below: @Node
public class BaseNode {
@Id
@GeneratedValue
private UUID id;
@Relationship(direction = Relationship.Direction.OUTGOING)
private Map<String, List<BaseRelationship>> relationships = new HashMap<>();
}
@RelationshipProperties
public abstract class BaseRelationship {
@RelationshipId
@GeneratedValue
private Long id;
@TargetNode
private BaseNode targetNode;
}
@RelationshipProperties
public class RelationshipA extend BaseRelationship{
String a;
}
@RelationshipProperties
public class RelationshipAA extend RelationshipA{
String aa;
}
@RelationshipProperties
public class RelationshipB extend BaseRelationship{
String b;
} I want the
But, In this scenario, If I get the Node with relationships, I will get:
or
The type recognized by SDN is wrong, the code: Lines 314 to 326 in f10c95f
I dig into the code, found relationship type recognition use same code with node. Because empty of But I found,when constructing relationship,the For Node, it is same, before call And for relationship the queryResult has property And I test it, it works. so I create this issue and the pr
I think this can answer your question |
I think the database do save the type of relationship, but different from node. the type of relation saved as |
Given your example, I used your changes and created this test: @Test
void testTypeMapping(@Autowired BaseNodeRepository baseNodeRepository) {
var node = new BaseNode();
RelationshipA e1 = new RelationshipA();
e1.setTargetNode(new BaseNode());
RelationshipB e2 = new RelationshipB();
e2.setTargetNode(new BaseNode());
node.setRelationships(Map.of(
"relation", List.of(
e1, e2
)
));
var persistedNode = baseNodeRepository.save(node);
var loadedNode = baseNodeRepository.findById(persistedNode.getId()).get();
List<BaseRelationship> relationships = loadedNode.getRelationships().get("relation");
assertThat(relationships).hasExactlyElementsOfTypes(RelationshipA.class, RelationshipB.class);
} (Hope this is also your assumption) The only chance I see, how SDN could be helped determine which type to instantiate would be check on incoming properties on the relationship. There is only one type on relationships and because you are using the dynamic relationship approach, this will always be the same type for a list. There is just no chance to detect in this case what is the right relationship class to instantiate. |
@meistermeier hi, I check it again, I was wrong for this, I'm sorry for this. Here is the right test for me, the relationship type from key in map, I misunderstand this But the bug still here, if I set type, and set list of same type relations, still not get right instance. if the type is the simpleClassName, my PR works (but it's not good to solve this) void testTypeMapping(@Autowired BaseNodeRepository baseNodeRepository) {
var node = new BaseNode();
RelationshipA a1 = new RelationshipA();
RelationshipB b1 = new RelationshipB();
a1.setTargetNode(new BaseNode());
b1.setTargetNode(new BaseNode());
node.setRelationships(Map.of(
RelationshipA.class.getSimpleName(), List.of(a1),
RelationshipB.class.getSimpleName(), List.of(b1)
));
var persistedNode = baseNodeRepository.save(node);
var loadedNode = baseNodeRepository.findById(persistedNode.getId()).get();
List<BaseRelationship> relationshipsA = loadedNode.getRelationships().get(RelationshipA.class.getSimpleName());
List<BaseRelationship> relationshipsB = loadedNode.getRelationships().get(RelationshipB.class.getSimpleName());
assertThat(relationshipsA).hasExactlyElementsOfTypes(RelationshipA.class);
assertThat(relationshipsB).hasExactlyElementsOfTypes(RelationshipB.class);
} I am wander, is there any property for relation like label we can set the class type information in it? |
@meistermeier Hi, I update my PR, and that can fix all. You can test with the code in the PR. I add And When get labels to determine the type, get With this change, we can get proper type in a list of relations. |
I had a look at your update. Providing a type hint for keeping the information in place, is in general a good idea. Solving this by adding technical parameters as properties in the database on the other hand is nothing I want SDN to do. |
@meistermeier haha, I know you will say that. I admit that add a property is not a good way to do, but is the only way as you say. I agree that adding an annotation parameter is a good idea, but I don't know how to do this. |
My idea would be that a boolean parameter gets added to the |
@meistermeier I can imagine your idea, what I am confused is where to proper get the annotation property. In Line 231 in a6d15d2
Is it a proper way? If it is I can do this. |
You have access to the Line 234 in e5ac953
This would end up in something like
of course...naming is up to you 😃 |
@meistermeier okay, I will try this tomorrow. |
Take your time. And don't hesitate to ask questions or push unpolished code. We will support you. |
@meistermeier Hi, I pushed new commit to PR, you can check it |
Add an optional parameter to `@RelationshipProperties` that allows users to persist the type information on this relationship. This will allow SDN to detect the right class it needs to instantiate if, due to abstraction of the implementation, no other information is available. Closes #2973 Signed-off-by: 杨耀飞 <[email protected]> Signed-off-by: yangyaofei <[email protected]> Signed-off-by: Gerrit Meier <[email protected]> Co-authored-by: Gerrit Meier <[email protected]> (cherry picked from commit 7490d99)
Add an optional parameter to `@RelationshipProperties` that allows users to persist the type information on this relationship. This will allow SDN to detect the right class it needs to instantiate if, due to abstraction of the implementation, no other information is available. Closes #2973 Signed-off-by: 杨耀飞 <[email protected]> Signed-off-by: yangyaofei <[email protected]> Signed-off-by: Gerrit Meier <[email protected]> Co-authored-by: Gerrit Meier <[email protected]> (cherry picked from commit 7490d99)
Add an optional parameter to `@RelationshipProperties` that allows users to persist the type information on this relationship. This will allow SDN to detect the right class it needs to instantiate if, due to abstraction of the implementation, no other information is available. Closes #2973 Signed-off-by: 杨耀飞 <[email protected]> Signed-off-by: yangyaofei <[email protected]> Signed-off-by: Gerrit Meier <[email protected]> Co-authored-by: Gerrit Meier <[email protected]> (cherry picked from commit 7490d99)
If I have a BaseNode with Map type relationships defined with a base class
And I have two real class for relationship:
If there is a BaseNode with both two relationships :
Since SDN in node can get right instance, I think the relationship will get right,
but the code below, the relationships will get same type of instance, both the
Relationship
orAnotherRelationship
, cannot Get Proper type.The text was updated successfully, but these errors were encountered: