lphuberdeau / Neo4j-PHP-OGM

A doctrine2 style library to access neo4j graphs
156 stars 45 forks source link

Remove simple relationship #113

Open vladrolandomihai opened 7 years ago

vladrolandomihai commented 7 years ago

I can't figure out how to remove a simple relationship. Suppose I have a Person Entity which has a collection of friends (also Person). Say John is friend with Jimmy. I did the following:

$john->removeFriend($jimmy); // already retrieved from db
$em->flush();

and the removeFriend function in Person class looks like this:

function removeFriend($person) {
    if ($this->friends->contains($person)) {
        $this->friends->remove($person);
    }
}

The in-memory collection is updated. John is not friend with Jimmy anymore. However, this is not persisted into the db.

lphuberdeau commented 7 years ago

Based on what I see in the tests, you may just be missing a persist() call on the entity to add it to the working set.

https://github.com/lphuberdeau/Neo4j-PHP-OGM/blob/master/lib/HireVoice/Neo4j/Tests/EventManagerTest.php#L148

vladrolandomihai commented 7 years ago

The code you showed me works:

$jim = $em->getRepository('AppBundle\Entity\Person')->findOneByName('Jim');
$firstFriend = $jim->getFriends()->first(); // Returns John
$jim->removeFriend($firstFriend);
$em->persist($jim);
$em->flush();

However the folowing code does not work;

$jim = $em->getRepository('AppBundle\Entity\Person')->findOneByName('Jim');
$john = $em->getRepository('AppBundle\Entity\Person')->findOneByName('John');
$jim->removeFriend($john);
$em->persist($jim);
$em->flush();

In the second case, John is removed from the Friend's Array Collection in-memory but it is not persisted in the Database.

lphuberdeau commented 7 years ago

Seems like a good test case. Feel free to submit a PR with a fix.

vladrolandomihai commented 7 years ago

I have done some tests and from the results I concluded that the

getFriends() or getActors()

method call before

$em->persist()
$em->flush()

triggers the update in the database. I have tried calling other methods and also renaming the getFriends() to getFriendss() and in those casses, the entity is not persisted. I am not sure what might cause this and I would really appreciate if someone could have a look into this.

lphuberdeau commented 7 years ago

It's quite likely that the relationship needs to be hydrated first for the change to be detected. Fixing this would require re-writing most of the proxy generation to use a collection type that keeps track of those changes instead of just comparing them at the end.

If you are up to the task, I would gladly assist and review the changes. However, I no longer actively maintain this component.