1
votes

I am trying to create relationships between nodes in Neo4j. I am using the Neo4J(2.1.8 Community) & spring-data-neo4j(3.3.0.RELEASE).

I am trying to create the below relation.

Create a new Employee(node) which will be reporting(Empty Relation) to the Manager(node) which is there in DB (Searching by name). I have used the below query.

public interface EmployeeRepository extends GraphRepository<Employee> {

@Query("START employee=node:({0}), manager=node:Employee(name={1}) CREATE employee-[:REPORTS_TO]->manager")
void addNewEmployee(Employee employee, String managerName);}

I got the below error.

Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement START employee=node:({0}), manager=node:Employee(name={1}) CREATE employee-[:REPORTS_TO]->manager; nested exception is Invalid input '(': expected whitespace or an identifier (line 1, column 21)
"START employee=node:({0}), manager=node:Employee(name={1}) CREATE employee-[:REPORTS_TO]->manager"
                     ^

Can anyone please tell me what is wrong with this query? Also if this is not the right way to create the relations using GraphRepository then what else I can use to accomplish the same.

Thanks in advance.

Note: I have used this to learn the queries in Spring Data for Neo4j. Where they have shown the basic queries.

Updated: Employee Class

@NodeEntity
public class Employee {

@GraphId
private Long id;
private String name;
private String department;

@RelatedTo(type = "REPORTS_TO")
private Employee reportsTo;

@RelatedTo(type = "REPORTS_TO", direction = Direction.INCOMING)
Set<Employee> directReport;

public Employee() {
}

public Employee(String name, String department) {
    this.name = name;
    this.department = department;
}

public Long getId() {
    return id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDepartment() {
    return department;
}

public void setDepartment(String department) {
    this.department = department;
}

public Employee getReportsTo() {
    return reportsTo;
}

public void setReportsTo(Employee reportsTo) {
    this.reportsTo = reportsTo;
}

public Set<Employee> getDirectReport() {
    return directReport;
}

public void setDirectReport(Set<Employee> directReport) {
    this.directReport = directReport;
}

@Override
public int hashCode() {
    return super.hashCode();
}

@Override
public boolean equals(Object obj) {
    return super.equals(obj);
}

@Override
public String toString() {
    return "Employee{" + "id=" + id + ", name=" + name + ", department=" + department + '}';
}
}
1
For starters, there shouldn't be a colon between the node function and its argument. Try just employee=node({0})Dan
I have tried this but now its giving the new error. Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Error executing statement START employee=node({0}), manager=node:Employee(name={1}) CREATE employee-[:REPORTS_TO]->manager; nested exception is org.neo4j.cypher.MissingIndexException: Index Employee does not existmevada.yogesh
Even for the simple query START employee=node:Employee(name={0}) RETURN employee It is giving the same exception.mevada.yogesh
Have you tried MATCHing the name instead, as in START employee=node({0}) MATCH (manager:Employee) WHERE manager.name = {1} CREATE employee-[:REPORTS_TO]->manager? The docs seem to suggest that START is being made obsolete anywayDan
Thanks Dan for your support. I have tried the same but there is still error. But this time its different. Error executing statement START employee=node({0}) MATCH (manager:Employee) WHERE manager.name = {1} CREATE employee-[:REPORTS_TO]->manager; nested exception is org.neo4j.cypher.CypherTypeException: Expected a propertycontainer or number here, but got: Employee{id=null, name=Developer2, department=Development}mevada.yogesh

1 Answers

1
votes

Please show the definition of employee!

You can also use template.createRelationshipBetween(nodeOrEntity,nodeOrEntity2,type)

For your example this should work:

public interface EmployeeRepository extends GraphRepository {

@Query("MATCH (employee:Employee), (manager:Employee) 
       WHERE id(employee) = {0} AND manager.name = {1}
       CREATE employee-[:REPORTS_TO]->manager")
void addNewEmployee(Employee employee, String managerName);
}

perhaps better use, employee as a data-container / map for employee or just pass in the name directly:

@Query("MATCH (employee:Employee), (manager:Employee) 
       WHERE employee.name = {0}.name AND manager.name = {1}
       CREATE employee-[:REPORTS_TO]->manager")
void addNewEmployee(Employee employee, String managerName);
}