Comments (6)
I implemented a hotfix that works for my current setup. I have a mappedBy annotation defined on all relationships with relationship entities.
Code to be inserted in GraphAware\Neo4j\OGM\Hydrator\EntityHydrator right after
$targetEntity = $otherHydrator->hydrateNode($targetNode);
First determine what is start node and what is end node
/*
* Bugfix:
* If Relationship Entity start node and end node are of the same class, determine the start node
* and end node based on the mapping given in the annotation
*/
$startNodeIsSourceEntity = false;
if ($relationshipEntityMetadata->getStartNodeClass() == $relationshipEntityMetadata->getEndNodeClass()) {
if (!$relationshipMetadata->getMappedByProperty()) {
throw new \Exception('Invalid RelationshipEntity annotations. You need to define a mappedBy'
. ' annotation if startNode and endNode in a RelationshipEntity are of the same class');
}
if ($relationshipMetadata->getDirection() == Direction::OUTGOING) {
$startNodeIsSourceEntity = true;
} else {
$startNodeIsSourceEntity = false;
}
// TODO: BOTH
} else if ($relationshipEntityMetadata->getStartNodeClass() === $this->_classMetadata->getClassName()) {
$startNodeIsSourceEntity = true;
}
And then adjust the ste start node and set end node conditions
// set the start node
#if ($relationshipEntityMetadata->getStartNodeClass() === $this->_classMetadata->getClassName()) {
if ($startNodeIsSourceEntity) {
$relationshipEntityMetadata->setStartNodeProperty($entity, $sourceEntity);
} else {
$relationshipEntityMetadata->setStartNodeProperty($entity, $targetEntity);
}
// set the end node
#if ($relationshipEntityMetadata->getEndNodeClass() === $this->_classMetadata->getClassName()) {
if (!$startNodeIsSourceEntity) {
$relationshipEntityMetadata->setEndNodeProperty($entity, $sourceEntity);
} else {
$relationshipEntityMetadata->setEndNodeProperty($entity, $targetEntity);
}
This works only for INCOMING and OUTGOING directions, not for directions marked with BOTH
from neo4j-php-ogm.
There is another issue on n:m relationships with RelationshipEntities.
// guess the name of the property on the other node
foreach ($otherMetadata->getRelationships() as $rel) {
if ($rel->isRelationshipEntity()
&& $rel->getRelationshipEntityClass() === $relationshipEntityMetadata->getClassName()
) {
if (!$rel->isCollection()) {
$rel->setValue($targetEntity, $entity);
} else {
$rel->initializeCollection($targetEntity);
$rel->addToCollection($targetEntity, $entity);
}
}
}
The line $rel->addToCollection($targetEntity, $entity); adds the entity to the inverse side of the collection, but the inverse side is not initialized correctly (proxy stays on not initialized). This results in entities getting added twice to the ArrayCollection as soon as they are read on the inverse side (the initialize method is then called and the result set is added to the array collection).
Sorry, I am quite busy right now so I can't really look into it now. Uncommenting this line works for now. The effect is that more queries need to be send to the database, but on the other hand the results are correct.
I will try to come with concrete test cases, but this will take a few weeks.
from neo4j-php-ogm.
And in General: Determining the other side of the relationship by guessing the class name will result in quite some issues in any case where 2 Entities are related more than one time. E.g., (:User)-[:LIKES {since: 123}]->(:Company) and (:User)-[:VISITED {onDate: 123}]->(:Company).
from neo4j-php-ogm.
Thanks @sts85 , for this part :
The line $rel->addToCollection($targetEntity, $entity); adds the entity to the inverse side of the collection, but the inverse side is not initialized correctly (proxy stays on not initialized). This results in entities getting added twice to the ArrayCollection as soon as they are read on the inverse side (the initialize method is then called and the result set is added to the array collection).
This is fixed by #108 .
I will look at the other issue.
from neo4j-php-ogm.
Hi,
I just updated my dev environment to RC6 (I was still working on RC3 with my hotfix).
But RC-6 still does not work with my model.
Commenting out these lines of code in EntityHydrator
// TODO: HOTFIX by sts - does not work properly
// $startNodePropertyName = $relationshipEntityMetadata->getStartNodePropertyName();
// $sourceEntityMappedName = $relationshipMetadata->getMappedByProperty();
//
// $startNodeIsSourceEntity = $startNodePropertyName === $sourceEntityMappedName;
And using these lines
/*
*
* Eliminate error described in https://github.com/graphaware/neo4j-php-ogm/issues/106
* If Relationship Entity start node and end node are of the same class, determine the start node
* and end node based on the mapping given in the annotation
*/
$startNodeIsSourceEntity = false;
if ($relationshipEntityMetadata->getStartNodeClass() == $relationshipEntityMetadata->getEndNodeClass()) {
if (!$relationshipMetadata->getMappedByProperty()) {
throw new \Exception('Invalid Relationship Entity annotations. You need to define a mappedBy'
. ' annotation if startNode and endNode in a RelationshipEntity are of the same class');
}
if ($relationshipMetadata->getDirection() == Direction::OUTGOING) {
$startNodeIsSourceEntity = true;
} else if ($relationshipMetadata->getDirection() == Direction::INCOMING) {
$startNodeIsSourceEntity = false;
} else {
throw new \Exception('Invalid Relationship Entity annotations. Direction BOTH not supported on'
. 'RelationshipEntities where startNode and endNode are of the same class');
}
// TODO: BOTH
} else if ($relationshipEntityMetadata->getStartNodeClass() === $this->_classMetadata->getClassName()) {
$startNodeIsSourceEntity = true;
}
Makes it work again. I will look into this issue in a while, for now I will continue with the hotfix.
from neo4j-php-ogm.
The issue still exists, the test added with the fix does not verify the records assigned inside of the relation. Will send a PR with adjusted test to reproduce the issue.
from neo4j-php-ogm.
Related Issues (20)
- Difference between $query->getResult() and $repository->findOneBy(['uuid' => $uuid]) HOT 1
- When a key annotation is specified on a class property, the property name can't be used in findBy anymore.
- Add support for property converters to findBy.
- Relations between Nodes of the same type do not respect direction HOT 2
- Duplicate initialization of LazyCollection
- symfony 4 support HOT 10
- BaseRepository matching method
- [request] SQL Server graph tables HOT 1
- Add support for temporal and geospatial data types
- Hydrating RelationshipEntity objects HOT 1
- add EntityManagerInterface::createQuery HOT 2
- Can't register event listener from services.yml HOT 1
- neo4j-php-ogm not compatible with Cypher 3.2 ?
- Symfony 4.3 deprecated dispatch call
- Symfony 5 support HOT 1
- DateTimeConverter should allow DateTimeInterface instances
- Neo4jException DateTime is not supported as a return type in Bolt protocol version 1. Please make sure driver supports at least protocol version 2. Driver upgrade is most likely required.
- conflict with your requirements or minimum-stability
- Symfony 5 + PHP 8 support
- Abandoned repo?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from neo4j-php-ogm.