Total Pageviews

2018/07/15

[Spring Data] [Neo4j] Caused by: org.neo4j.driver.v1.exceptions.ClientException: Invalid input '{': expected whitespace or a rel type name

Problem
假設我想建立下圖 User nodes 間 IS_FRIEND_OF 與 WORKS_WITH 的關係


透過 Spring Data 建立以下的 repository class (分別傳入三個參數,包含來源 node、目的 node以及要建立的關係)
package neo4j.springdata.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import neo4j.springdata.vo.User;

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
    
    @Query(" match (from:User), (to:User) " + 
           " where from.name={from} and to.name={to} " + 
           " merge (from)-[:{relation}]->(to) ")
    void createRelation(@Param("from") String from, @Param("to") String to, @Param("relation") String relation);

} 

但在執行時,出現以下 runtime exception
Caused by: org.neo4j.driver.v1.exceptions.ClientException: Invalid input '{': expected whitespace or a rel type name (line 1, column 87 (offset: 86))
"match (from:User), (to:User)  where from.name={from} and to.name={to}  merge (from)-[:{relation}]->(to)"
                                                                                       ^
 at org.neo4j.driver.internal.net.SocketResponseHandler.handleFailureMessage(SocketResponseHandler.java:76)
 at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.unpackFailureMessage(PackStreamMessageFormatV1.java:470)
 at org.neo4j.driver.internal.messaging.PackStreamMessageFormatV1$Reader.read(PackStreamMessageFormatV1.java:431)
 at org.neo4j.driver.internal.net.SocketClient.receiveOne(SocketClient.java:196)
 at org.neo4j.driver.internal.net.SocketConnection.receiveOne(SocketConnection.java:217)
 at org.neo4j.driver.internal.net.ConcurrencyGuardingConnection.receiveOne(ConcurrencyGuardingConnection.java:165)
 at org.neo4j.driver.internal.net.pooling.PooledSocketConnection.receiveOne(PooledSocketConnection.java:183)
 at org.neo4j.driver.internal.InternalStatementResult.receiveOne(InternalStatementResult.java:335)


How-To
根據 neo4j 於 gitlab 上的說明: https://github.com/neo4j/neo4j/issues/4334
目前在 relation 的部分,尚未支援參數化傳遞。因此,根據需求,須將其拆成兩個 methods,建立兩種不同的 relationships
package neo4j.springdata.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import neo4j.springdata.vo.User;

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
    
    @Query(" match (from:User), (to:User) " + 
           " where from.name={from} and to.name={to} " + 
           " merge (from)-[:WORKS_WITH]->(to) ")
    void createWorksWithRelation(@Param("from") String from, @Param("to") String to);
 
    @Query(" match (from:User), (to:User) " + 
           " where from.name={from} and to.name={to} " + 
           " merge (from)-[:IS_FRIEND_OF]->(to) ")
    void createIsFriendOfRelation(@Param("from") String from, @Param("to") String to);

}



No comments: