In fact, as I'm migrating my spring project to SDN 6.x and after your explanations, the best way will be to :
- remove all relationships from all java nodes
- if a relation has to be added, changed or removed, then use a custom method
- do not use ClosedProjection (not needed)
-> Why ? because i have big trees with a lot of relations between nodes and, for performance reason, I don't want to load all trees each time i need to load a node, add or update a relation....
The problem now, is to get relationship (still from spring) :
As :
neo4jTemplate.findAll("MATCH(u:User)-[r:HAS_USER_ACTIVITIES]->(ro:Activity) WHERE id(u) = $userId RETURN r", Collections.singletonMap("userId", userId), UserActivityRelationship.class);`
Do not work (because it return a relatioship), I have to do :
(List<UserActivityRelationship>) neo4jClient.query("MATCH(u:User)-[r:HAS_USER_ACTIVITIES]->(ro:Activity) WHERE id(u) = $userId RETURN r").bindAll( Collections.singletonMap("userId", userId)).fetchAs(UserActivityRelationship.class).
mappedBy((typeSystem, record) -> mapUserActivityRelationship( record )).all();
with :
protected UserActivityRelationship mapUserActivityRelationship( Record record ) {
UserActivityRelationship userActivityRelationship = new UserActivityRelationship();
Relationship relationship = record.get(0).asRelationship();
userActivityRelationship.setId(relationship.id());
userActivityRelationship.setActivity(activityRepository.getById(relationship.endNodeId()));
if ( !relationship.get("userActivityType").isNull())
userActivityRelationship.setUserActivityType(UserActivityTypeEnum.valueOf(relationship.get("userActivityType").asString()));
if ( ! relationship.get("center").isNull())
userActivityRelationship.setCenter( new Point(relationship.get("center").asPoint().x(), relationship.get("center").asPoint().y()));
if ( ! relationship.get("level").isNull())
userActivityRelationship.setLevel(UserLevelEnum.valueOf(relationship.get("level").asString()));
if ( ! relationship.get("rangeType").isNull())
userActivityRelationship.setRangeType(RangeTypeEnum.valueOf(relationship.get("rangeType").asString()));
if ( ! relationship.get("range").isNull())
userActivityRelationship.setRange(relationship.get("range").asDouble());
return userActivityRelationship;
}
And to create relationship.. :
@Query(
"MATCH (u:User) OPTIONAL MATCH (a:Activity) WHERE id(u) = $userId AND id(a) = $activityId "
+ "MERGE (u)-[r:HAS_USER_ACTIVITIES]->(a) "
+ "SET r = {userActivityType: $userActivityType, center: $center, level: $level, rangeType: $rangeType, range: $range} RETURN id(r)")
Long addUserActivity(@Param("userId") Long userId,
@Param("activityId") Long activityId,
@Param("userActivityType") UserActivityTypeEnum userActivityType,
@Param("center") Point center, @Param("level") UserLevelEnum level,
@Param("rangeType") RangeTypeEnum rangeType, @Param("range") Double range);
Is it the right way ? do you have any improvement ?
Migrating to SDN 6 is a huge work... it generate much more code than before.
Thanks for help