Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-10-2020 01:36 AM
Hi guys,
I'm trying to remove a relationship from an @NodeEntity, when using debugger, the breakpoints indicates that the object isn't containing any relation in outgoingRelations
and incomingRelations
but when the transaction is comitted, it refills the outgoingRelations
with the relation I just removed... I don't understand why, but after a long debug, I found that the OGM never identified that the relations had changed, the only statement being executed in the DB is the one to update the Node body only.
Do you guys have any idea on how to fix that ? here's my code :
//BaseNode.java
public class BaseNode extends BaseGraphObject {
@Properties
protected Map<String, Object> attributes;
@Relationship(type = "RELATION")
protected List<BaseRelation> outgoingRelations;
@Relationship(type = "RELATION", direction = Relationship.INCOMING)
protected List<BaseRelation> incomingRelations;
protected Long x;
protected Long y;
public BaseNode() {
super();
this.attributes = new HashMap<>();
this.outgoingRelations = new ArrayList<>();
this.incomingRelations = new ArrayList<>();
}
public List<BaseRelation> getIncomingRelations() {...}
public List<BaseRelation> getOutgoingRelations() {...}
//BaseNodeUtil.java
public static void updateRelations(BaseNode node, Map<Object, Object> json, Session session) throws ApiException {
// [...]
for(int i = 0 ; i < node.getOutgoingRelations().size(); i++) {
BaseRelation relation = node.getOutgoingRelations().get(i);
if(!relation.getType().equals(RelationType.GROUP.toString()))
node.getOutgoingRelations().remove(i);
}
}
//BaseNodeEditHandler.java
public class BaseNodeEditHandler extends AsyncHandler {
@Override
public boolean asyncTask(ApiCompletableFuture api, Context context, Session session) throws Exception {
BaseDefinition definition = repository.find(Long.parseLong(context.pathParam("id")));
definition.setIcon(Icon.valueOf(json.get("icon").toString()));
definition.setX(Long.valueOf(json.get("x").toString()));
definition.setY(Long.valueOf(json.get("y").toString()));
BaseNodeUtil.updateRelations(definition, json, session);
definition.validate();
definition = repository.createOrUpdate(definition, session);
return api.success("Definition has been successfully edited", GraphUtil.format(repository.find(definition.getId())));
}
}
Edit: I also noticed that removing the session
param from the createOrUpdate, fixed the problem, but I need it to work in a transaction that I can rollback on Exception
02-10-2020 04:17 AM
@gerrit.meier Sorry for the ping, but I think you're the only one who can help me on this 😕
02-10-2020 05:02 AM
As the relation I tried to remove is a RelationshipEntity, I directly did session.delete(relation)
which is working fine, but if you have the time, I would be glad to understand why my first attempt didn't worked
02-13-2020 12:10 AM
I wonder what your repository look like, or at least what repository.createOrUpdate(definition, session)
and repository.find(Long.parseLong(context.pathParam("id")))
do.
I assume that your are not using only using the Spring Data repository but something else because there is no createOrUpdate
method in there.
I assume that the loading of the definition
in the BaseNodeEditHandler
takes place in another session then the createOrUpdate
which makes Neo4j-OGM unaware of the already existing relationships and cannot decide if it needs to get deleted or not.
02-17-2020 04:00 AM
Here is the createOrUpdate
method, its inside a GenericCrud<T>
(from the GenericService in this example: https://neo4j.com/docs/ogm-manual/current/tutorial/)
public abstract class GenericCrud<T> implements Crud<T> {
private static final int DEPTH_LIST = 0;
private static final int DEPTH_ENTITY = -1;
protected Session session = HedgeSessionFactory.getInstance().getSession();
public abstract Class<T> getEntityType();
@Override
public T find(Long id) {
Class<T> entityType = getEntityType();
return this.session.load(entityType, id, entityType.equals(BaseRelation.class) ? 1 : DEPTH_ENTITY);
}
@Override
public T find(Long id, Session session) {
Class<T> entityType = getEntityType();
return session.load(entityType, id, entityType.equals(BaseRelation.class) ? 1 : DEPTH_ENTITY);
}
@Override
public T createOrUpdate(T entity) {
this.session.save(entity, DEPTH_ENTITY);
return find(((BaseGraphObject) entity).getId());
}
@Override
public T createOrUpdate(T entity, Session session) {
session.save(entity, DEPTH_ENTITY);
return find(((BaseGraphObject) entity).getId());
}
}
02-17-2020 05:00 AM
I think my assumption is still valid. the createOrUpdate
uses the GenericCrud
class' session
but the find operates with a provided one. If those Session
s are not the same, they won't share a cache and the one that is responsible for the save does not know about the changes that happened in the entity but only "sees" the current state.
07-08-2021 12:10 AM
@gerrit.meier this is very common problem faced by many people including me but have not found a suitable solution. I have User Nodes in neo4j database. each user has contact relationship with some other users. now I want to delete this contact relationship for a user.
e.g. i have user1 and user2 relating with each other on contact relation.
User {
...properties
@Relationship("CONTACT")
public Set contacts = new HashSet<>():
}
now I am deleting for user1.getContacts().remove(user2); //it remove user2 from list ok
userRepo.save(user1); //but here it doesn't save these changes
07-08-2021 01:48 AM
Do you mean that you defined this on both sides? If so, you would also have to remove it in both User
contact lists.
07-12-2021 12:23 AM
[How to delete a relationship of a neo4j node in spring data - Stack Overflow](https://how to delete a relationship of a neo4j node in spring data) a question I asked on stackoverflow. If you can answer there Please.
I see this warning from spring boot and doesn't update the node WARN 12167 --- [nio-8080-exec-9] o.s.d.n.c.m.DefaultNeo4jIsNewStrategy : Instances of class com.talkkia.api.entity.User with an assigned id will always be treated as new without version property!
07-12-2021 05:06 AM
Ah....so this is unrelated to Neo4j-OGM but a SDN problem you are facing. Will answer on SO.
All the sessions of the conference are now available online