Good evening,
I'm currently working on an API controller used to edit some node entities and its relationships, the node update is working well but when I update the RelationshipEntities
inside the NodeEntity: Set<ContextRelation>
, its returning the NodeEntity, RelationshipEntities and duplicated RelationshipEntities (they got the same ID and have both the updated values).
Technologies used:
- Neo4J 4.0-rc1
- Neo4J-OGM 3.2.3 (bolt driver)
- Neo4J driver 4.0.0
- Javalin
Here is the final JSON example:
{
"data": {
"id": 5,
"contexts": [
{
"id": 18,
"min": 1,
"max": 1,
"definition": {
"id": 8,
"contexts": [],
}
},
{
"id": 18,
"min": 1,
"max": 1,
"definition": {
"id": 8,
"contexts": []
}
}
]
}
}
My aim is to change the "min" and "max" values without making Neo4J creating a new RelationshipEntity id.
Here is my ContextRelation.class
:
@RelationshipEntity(type = RelationType.Names.CONTEXT)
public class ContextRelation extends BaseRelation {
@StartNode
private BaseDefinition from;
@EndNode
private BaseDefinition to;
private Long min;
private Long max;
public ContextRelation() {}
public ContextRelation(BaseDefinition from, BaseDefinition to, Long min, Long max) {
this.from = from;
this.to = to;
this.min = min;
this.max = max;
}
@JsonProperty("definition")
public BaseDefinition getTo() {
return this.to;
}
public Long getMin() {
return this.min;
}
public void setMin(Long min) {
this.min = min;
}
public Long getMax() {
return this.max;
}
public void setMax(Long max) {
this.max = max;
}
}
BaseDefinition.class
:
@NodeEntity(label = NodeType.Names.DEFINITION)
public abstract class BaseDefinition extends BaseGraphObject {
@JsonFilter("DEPTH_ENTITY")
@Relationship(value = RelationType.Names.CONTEXT)
protected Set<ContextRelation> contexts;
public BaseDefinition() {
super();
this.contexts = new ConcurrentSet<>();
}
Here is the place where I edit Set<ContextRelation>
in the Controller:
if(json.get("contexts") instanceof List) {
Map<Long, Map<String, Object>> jsonContexts = new HashMap<>();
((List<Map<String, Object>>) json.get("contexts")).stream()
.filter(ContextRelation::validate)
.filter(c -> !jsonContexts.keySet().contains(Long.valueOf(c.get("definition").toString())))
.forEach(c -> jsonContexts.put(Long.valueOf(c.get("definition").toString()), c));
Map<Long, ContextRelation> definitionContexts = definition.getContexts().stream()
.collect(Collectors.toMap(c -> c.getTo().getId(), c -> c));
for(ContextRelation currentContext : definitionContexts.values()) {
if(!jsonContexts.keySet().contains(currentContext.getTo().getId())) {
definition.getContexts().remove(currentContext);
} else {
Map<String, Object> currentJsonContext = jsonContexts.get(currentContext.getTo().getId());
definition.getContexts().remove(currentContext);
currentContext.setMax(currentJsonContext.get("max") == null ? null : Long.valueOf(currentJsonContext.get("max").toString()));
currentContext.setMin(currentJsonContext.get("min") == null ? null : Long.valueOf(currentJsonContext.get("min").toString()));
definition.getContexts().add(currentContext);
definitionContexts.put(currentContext.getTo().getId(), currentContext);
}
}
for(Map<String, Object> currentContext : jsonContexts.values()) {
if(ContextRelation.validate(currentContext) && !definitionContexts.keySet().contains(Long.parseLong(currentContext.get("definition").toString()))) {
BaseDefinition contextDefinition = repository.find(Long.valueOf(currentContext.get("definition").toString()));
if(contextDefinition == null)
errors.put("contexts", "One context definition's id is incorrect");
else
definition.getContexts().add(
new ContextRelation(
definition,
contextDefinition,
currentContext.get("min") == null ? null : Long.parseLong(currentContext.get("min").toString()),
currentContext.get("max") == null ? null : Long.parseLong(currentContext.get("max").toString())
)
);
}
}
}
definition = repository.createOrUpdate(definition);
ApiUtils.respond(context, "Définition modifée avec succès", Response.OK, definition);
Do you guys have any idea about this problem ?
Thank you