neo4j / neo4j-ogm

Java Object-Graph Mapping Library for Neo4j
https://neo4j.com/docs/ogm-manual/
Apache License 2.0
337 stars 165 forks source link

Subsequent Object not Correctly read #144

Closed biliboc closed 6 years ago

biliboc commented 8 years ago

capture I have this domain object

`@NodeEntity(label="DataView") public class DataView extends AbstractNamedOwnedObject {

private DataViewType type;

@Relationship(type = "VIEW_PART", direction = Relationship.OUTGOING)
private Set<DataViewThingRel> viewParts;

@Relationship(type = "VIEW_REL", direction = Relationship.OUTGOING)
private Set<ViewThingRel> viewRels;

@Relationship(type = "VIEW_ATTR", direction = Relationship.OUTGOING)
private Set<ViewThingAttr> viewThingAttrs;

@Relationship(type= "HAS_ATTR", direction = Relationship.OUTGOING)
private Set<NodeAttr> attrs;

@Relationship(type= "OWNER", direction = Relationship.OUTGOING)
protected Thing owner;

@Relationship(type= "SHARED_WITH", direction = Relationship.OUTGOING)
private Set<Thing> sharedWith;

....

}`

and this query

START s=node(4028) MATCH (s:DataView)-[:OWNER|SHARED_WITH]->(u:_GraphUser_ {name:"cmitocar"}) WITH s MATCH p=()<-[:OWNER|SHARED_WITH*0..1]-(s)-[:VIEW_ATTR|VIEW_PART|VIEW_REL|DW_R_END|W_R_START|W_R_END|HAS_ATTR|W_HAS_ATTR*0..3]-(m) RETURN p
return session.queryForObject(DataView.class, "START s=node({sid}) MATCH (s:DataView)-[:OWNER|SHARED_WITH]->(u:_GraphUser_ {name:{username}}) WITH s MATCH p=()<-[:OWNER|SHARED_WITH*0..1]-(s)-[:VIEW_ATTR|VIEW_PART|VIEW_REL|DW_R_END|W_R_START|W_R_END|HAS_ATTR|W_HAS_ATTR*0..3]-(m) RETURN p", ImmutableMap.<String,Object>of( "sid", id, "username", username ) );

returns the right object BUT in the sharedWith field there is one entry that is the same value in the owner

As per image attached it should return @'cmitocar2' node.

SIMPLIFICATION:

REQUEST {"statements":[{"statement":"START s=node({sid}) MATCH (s:DataView)-[:OWNER|SHARED_WITH]->(u:_GraphUser_ {name:{username}}) WITH s MATCH p=()<-[:OWNER|SHARED_WITH]-(s) RETURN p","parameters":{"sid":4028,"username":"cmitocar"},"resultDataContents":["graph"],"includeStats":false}]} OUTPUT `

{
    "commit": "http://localhost:7478/db/data/transaction/12163/commit",
    "results":
    [
        {
            "columns":
            [
                "p"
            ],
            "data":
            [
                {
                    "graph":
                    {
                        "nodes":
                        [
                            {
                                "id": "22588",
                                "labels":
                                [
                                    "Thing",
                                    "_GraphUser_",
                                    "ThingWithRels",
                                    "AbstractNamedOwnedObject"
                                ],
                                "properties":
                                {
                                    "nameClosure": "CMITOCAR2",
                                    "modifiedDtTm": 1459918622367,
                                    "createdDtTm": 1459918622367,
                                    "name": "cmitocar2",
                                    "type": "_GraphUser_",
                                    "namelc": "cmitocar2"
                                }
                            },
                            {
                                "id": "4028",
                                "labels":
                                [
                                    "DataView",
                                    "AbstractNamedOwnedObject"
                                ],
                                "properties":
                                {
                                    "nameClosure": "TEST01",
                                    "modifiedDtTm": 1460442558693,
                                    "createdDtTm": 1459147255806,
                                    "name": "Test01",
                                    "type": "GRAPH",
                                    "namelc": "test01"
                                }
                            }
                        ],
                        "relationships":
                        [
                            {
                                "id": "26993",
                                "type": "SHARED_WITH",
                                "startNode": "4028",
                                "endNode": "22588",
                                "properties":
                                {
                                }
                            }
                        ]
                    }
                },
                {
                    "graph":
                    {
                        "nodes":
                        [
                            {
                                "id": "116",
                                "labels":
                                [
                                    "Thing",
                                    "_GraphUser_",
                                    "ThingWithRels",
                                    "AbstractNamedOwnedObject"
                                ],
                                "properties":
                                {
                                    "nameClosure": "CMITOCAR",
                                    "modifiedDtTm": 1458894979400,
                                    "createdDtTm": 1458894979400,
                                    "name": "cmitocar",
                                    "type": "_GraphUser_",
                                    "namelc": "cmitocar"
                                }
                            },
                            {
                                "id": "4028",
                                "labels":
                                [
                                    "DataView",
                                    "AbstractNamedOwnedObject"
                                ],
                                "properties":
                                {
                                    "nameClosure": "TEST01",
                                    "modifiedDtTm": 1460442558693,
                                    "createdDtTm": 1459147255806,
                                    "name": "Test01",
                                    "type": "GRAPH",
                                    "namelc": "test01"
                                }
                            }
                        ],
                        "relationships":
                        [
                            {
                                "id": "3961",
                                "type": "OWNER",
                                "startNode": "4028",
                                "endNode": "116",
                                "properties":
                                {
                                }
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "transaction":
    {
        "expires": "Tue, 12 Apr 2016 08:00:49 +0000"
    },
    "errors":
    [
    ]
}

`

luanne commented 8 years ago

@biliboc it looks like you're returning a path which contains both nodes- CMITOCAR and CMITOCAR2 with the same labels, so the OGM is unable to tell which node you're expecting. It is better to return the node you want, along with relationships and other nodes in the path (because I'm assuming you want a hydrated entity). http://graphaware.com/neo4j/2016/04/06/mapping-query-entities-sdn.html may be helpful.

biliboc commented 8 years ago

I really don't get it why you cannot do that: In the domain object the type of the relationship is stated: one is OWNER and the other one is SHARED_WITH. In the structure returned by the server those relationships are also returned including their differentiating type. So the distinction should not have stopped here just at the label of the sub object but use the type of the relationship. You have all the info necessary. At this level, OGM is introducing a unnecessary constraint as all the info needed is returned by the server.

luanne commented 8 years ago

What does Thing.java look like? And which version of the OGM are you using?

cmitocar commented 8 years ago
<neo4j.ogm.version>2.0.1</neo4j.ogm.version>

@NodeEntity(label="Thing")
public class Thing extends AbstractNamedOwnedObject implements Attributable {

    protected String type;

    protected String uuid;

    @Relationship(type= "HAS_ATTR", direction = Relationship.OUTGOING)
    protected Set<NodeAttr> attrs;

    @Relationship(type= "SHARED_WITH", direction = Relationship.OUTGOING)
    private Set<Thing> sharedWith;

    ....

}
luanne commented 8 years ago

So Thing does not have references back to DataView for the OWNER and SHARED_WITH relationships?

biliboc commented 8 years ago

It does not. By the way I do not use the repositories provided by SDN but using session.query() I built my own Repository interface as I did not like the constrains SDN is enforcing

luanne commented 8 years ago

Do you see the same mapping problem when you load the DataView by id? Using the session/template load/find one?

biliboc commented 8 years ago

The same problem when loading dataview by ID:

@Override
public T find( Long id, int depth ) {
    return session.load( getEntityType(), id, depth );
}
vince-bickers commented 8 years ago

Confirmed as a bug. As a temporary workaround, until we can provide a fix, we believe that if you are able to change the DataView's owner to List<Thing> owners rather than a singleton Thing owner, it will work as you expect. The owner will not appear in the List<Thing> shared collection.

Alternatively, if you add the corresponding incoming relationship to the singleton owner on the Thing it should also solve the problem:

    @Relationship(type="OWNER", direction = "INCOMING")
    DataView dataView;
biliboc commented 8 years ago

Ok I will do an workaround. You guys need to stop enforcing sub objects to have a link to parent objects. In my case the sub object represents a user which is a owner of thousands of objects. If, by mistake, I would have saved that object I would lose all the links to the objects that owns.

luanne commented 8 years ago

Deferred till entity mapping strategies are discussed. Another workaround is to annotate the setters as well in DataView.java

frant-hartm commented 7 years ago

This now seems to be working as expected?

https://github.com/neo4j/neo4j-ogm/blob/master/test/src/test/java/org/neo4j/ogm/persistence/examples/hierarchy/dualRelationships/DualRelationshipTest.java#L42

@luanne can you confirm?

frant-hartm commented 6 years ago

I think this now works as it should, if not please reopen with a test case provided.