4

오늘은 봄 데이터 Neo4j 시도 (독특한 = TRUE) @Indexed, 나는 마침내 내가 사용봄 데이터 Neo4j는 repository.save 및

... 어떻게 든작업 있어요 :

  • 봄 4.0.2
  • 봄 데이터 Neo4j 3.0.0
  • QueryDSL 3.3.1
  • Neo4j 2.0.1
01

@Configuration 
@EnableNeo4jRepositories([email protected](value=GraphRepository.class, type=FilterType.ASSIGNABLE_TYPE)) 
public class Neo4jConfig extends Neo4jConfiguration { 

    public Neo4jConfig() { 
     setBasePackage("my.base.package"); 
    } 

    @Bean 
    public GraphDatabaseService graphDatabaseService() { 
     return new GraphDatabaseFactory().newEmbeddedDatabase("/tmp/neo4j"); 
    } 

} 

내 도메인 클래스 : 23,516,

여기 내 설정이다

@NodeEntity 
@QueryEntity 
public class User implements Persistable<Long> { 

    @GraphId private Long id; 
    public Long getId() { return id; } 

    @NotNull @NotBlank @Email 
    @Indexed(unique=true) 
    private String email; 
    public String getEmail() { return email; } 
    void setEmail(String email) { this.email = email; } 

    @Override 
    public boolean isNew() { 
     return id==null; 
    } 

    @Override 
    public int hashCode() { 
     return id == null ? System.identityHashCode(this) : id.hashCode(); 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     User other = (User) obj; 
     if (id == null) { 
      if (other.id != null) 
       return false; 
     } else if (!id.equals(other.id)) 
      return false; 
     return true; 
    } 

} 

그리고 내 저장소 : 나는 성공적으로 DB에 사용자를 작성하고 나중에 검색 할 수 있습니다

interface UserRepository extends GraphRepository<User>, CypherDslRepository<User> {} 

그것을 통해 :

User u = repo.query(
    start(allNodes("user")) 
     .where(toBooleanExpression(QUser.user.email.eq("[email protected]"))) 
     .returns(node("user")), new HashMap<String, Object>()) 
    .singleOrNull(); 

하지만 : 지금 내 생성 코드를 두 번째로 호출하는 경우, 그것은 때문에 @Indexed(unique=true) String email의 예외가 발생하지 것, 그것은 바로 DB에있는 객체를 무시합니다.

다른 이메일 값으로 두 번째 User을 만들려고 시도하면 이전 사용자가 무효화됩니다.

User u = new User(); 
u.setEmail("[email protected]"); 
repo.save(u); 

가 나는 또한 정확히 같은 결과를 내장 한 대신 Neo4j의 독립 실행 형 버전을 사용하려고 : 같이 코드를 작성

은 간단합니다.

2014-03-12 21:00:34,176 DEBUG o.s.data.neo4j.support.schema.SchemaIndexProvider: 35 - CREATE CONSTRAINT ON (n:`User`) ASSERT n.`email` IS UNIQUE 
2014-03-12 21:00:34,177 DEBUG  o.s.data.neo4j.support.query.CypherQueryEngine: 63 - Executing cypher query: CREATE CONSTRAINT ON (n:`User`) ASSERT n.`email` IS UNIQUE params {} 

좀 더 디버그 출력 :

curl -v http://localhost:7474/db/data/index/node 

{ 
    "User" : { 
    "template" : "http://localhost:7474/db/data/index/node/User/{key}/{value}", 
    "provider" : "lucene", 
    "type" : "exact" 
} 


curl -v http://localhost:7474/db/data/schema/index 

[ { 
    "property_keys" : [ "email" ], 
    "label" : "User" 
} ] 


curl -v http://localhost:7474/db/data/schema/constraint 

[ { 
    "property_keys" : [ "email" ], 
    "label" : "User", 
    "type" : "UNIQUENESS" 
} ] 

Node Indexes:     Relationship Indexes: 

User  {"type":"exact"}  __rel_types__ {"type":"exact"} 
lucene      lucene 

디버그 출력도 봄 인덱스를 생성 하더군요 다음으로 WebAdmin보기에서 나는 어떤 인덱스를 생성 것을 볼 수 있습니다

나는 여기서 내가 잘못하고있는 것을 상상할 수 없다 ...

도와주세요!


1 UPDATE 번호 : 나는 항상 "생각"내 실체 것으로 가정

그래서
Stores the given entity in the graph, if the entity is already attached to the graph, the node is updated, otherwise a new node is created. 

: 나는 AbstractGraphRepository.save에서 무엇을 본 적이에서

는 말한다 Neo4jTemplate.save를 사용 이미 첨부되어 있습니다. 그러나 ?


UPDATE # 2 :

난으로 WebAdmin에 가서 간단하게 두 번 할 경우

:

CREATE (n:User {email:'[email protected]'}) 

나는 오류가 발생합니다.

봄 데이터 Neo4j의 save 방법이하는 일 GET 같은 또는 CREATE :

User u1 = new User(); 
u1.setEmail("[email protected]"); 
repo.save(u1); // creates node with id=0 

User u2 = new User(); 
u2.setEmail("[email protected]"); 
repo.save(u2); // creates node with id=1 

User u3 = new User(); 
u3.setEmail("[email protected]"); 
repo.save(u3); // updates and returns node with id=0 
그래서 내 자바 코드 또는 SDN에 뭔가 문제 ...


UPDATE # 3이 있어야합니다

이 문제는 어떻게 해결할 수 있습니까? 나는 예외를 원해.


UPDATE # 4 : 그 찾고있는 것처럼

이 보인다 :

: http://docs.neo4j.org/chunked/stable/rest-api-unique-indexes.html#rest-api-create-a-unique-node-or-return-fail-create

Map<String, Object> prop1 = new HashMap<String, Object>(); 
prop1.put("email", "[email protected]"); 
neo4jTemplate.createNodeAs(User.class, prop1); 

Map<String, Object> prop2 = new HashMap<String, Object>(); 
prop2.put("email", "[email protected]"); 
neo4jTemplate.createNodeAs(User.class, prop2); 

가 예상 작동하기 때문에이 방법은, 적어도 나는 예외가

org.neo4j.rest.graphdb.RestResultException: Node 7 already exists with label User and property "email"=[[email protected]] 

하지만 지금은 어떻게 int 당신이 SDN을 사용하는 경우 3.2.0+ ... 봄 데이터 저장소로

+0

감사합니다. 그것에 대해 jira 문제를 제기 할 수 있습니까? 아마도이 동작을 위해 @Indexed에 특성을 추가해야할까요? –

+0

이미 했어요 : https://jira.spring.io/browse/DATAGRAPH-445 –

답변

2

을이 egrate failOnDuplicate 속성 사용 : 당신의 의견을 당신을 위해

@Indexed(unique = true, failOnDuplicate = true)