[SPRING] Spring 데이터 Neo4j - repository.save와 @Indexed (unique = true)
SPRINGSpring 데이터 Neo4j - repository.save와 @Indexed (unique = true)
오늘 나는 Spring Data Neo4j를 시도했다.
나는 다음을 사용하고있다 :
내 설정은 다음과 같습니다.
@Configuration
@EnableNeo4jRepositories(includeFilters=@Filter(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");
}
}
내 도메인 클래스 :
@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;
}
}
그리고 나의 저장소 :
interface UserRepository extends GraphRepository<User>, CypherDslRepository<User> {}
나는 DB에서 사용자를 성공적으로 만들 수 있으며 이후에 다음을 통해 검색 할 수 있습니다.
User u = repo.query(
start(allNodes("user"))
.where(toBooleanExpression(QUser.user.email.eq("my@email.com")))
.returns(node("user")), new HashMap<String, Object>())
.singleOrNull();
하지만 : 이제 두 번째로 작성 코드를 호출하면 @Indexed (unique = true) 문자열 전자 메일 때문에 예외가 발생하지 않고 DB의 객체를 재정의합니다.
AND : 다른 이메일 값을 가진 두 번째 사용자를 만들려고하면 이전 사용자가 무시됩니다.
create 코드는 다음과 같이 간단합니다.
User u = new User();
u.setEmail("some@email-address.com");
repo.save(u);
또한 임베디드 버전 대신 독립형 버전의 Neo4j를 사용하려고 시도했습니다. 정확히 같은 결과가 나타납니다. webadmin보기에서 나는 그것이 몇개의 인덱스를 생성했다는 것을 알 수있다.
Node Indexes: Relationship Indexes:
User {"type":"exact"} __rel_types__ {"type":"exact"}
lucene lucene
디버그 결과는 Spring이 인덱스를 생성한다는 것을 알려준다.
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"
} ]
나는 내가 여기서 잘못하고있는 것을 상상할 수 없다 ...
제발 도와주세요!
업데이트 # 1 :
내가 AbstractGraphRepository.save에서 본 것은 다음과 같은 Neo4jTemplate.save를 사용합니다 :
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.
그래서 나는 항상 내 존재가 이미 첨부되어 있다고 생각한다고 생각합니다. 그런데 왜?
업데이트 # 2 :
webadmin으로 가서 두 번만하면됩니다.
CREATE (n:User {email:'test@mail.com'})
오류가 발생했습니다. 그래서 내 Java 코드 나 SDN에 문제가있을 것입니다 ...
업데이트 # 3 :
Spring 데이터 Neo4j의 save 메소드는 GET 또는 CREATE와 같은 작업을 수행합니다.
User u1 = new User();
u1.setEmail("a@email.com");
repo.save(u1); // creates node with id=0
User u2 = new User();
u2.setEmail("b@email.com");
repo.save(u2); // creates node with id=1
User u3 = new User();
u3.setEmail("a@email.com");
repo.save(u3); // updates and returns node with id=0
어떻게이 문제를 해결할 수 있습니까? 나는 예외를 원해.
업데이트 # 4 :
내가 찾던 것처럼 보입니다 : http://docs.neo4j.org/chunked/stable/rest-api-unique-indexes.html#rest-api-create-a-unique-node-or-return-fail- 몹시 떠들어 대다
Map<String, Object> prop1 = new HashMap<String, Object>();
prop1.put("email", "abc@mail.com");
neo4jTemplate.createNodeAs(User.class, prop1);
Map<String, Object> prop2 = new HashMap<String, Object>();
prop2.put("email", "abc@mail.com");
neo4jTemplate.createNodeAs(User.class, prop2);
이 방법은 예상대로 작동하지만 적어도 예외가 발생합니다.
org.neo4j.rest.graphdb.RestResultException: Node 7 already exists with label User and property "email"=[abc@mail.com]
하지만 지금은 이것을 Spring Data Repository와 통합하는 방법을 알 수 없습니다 ...
해결법
-
==============================
1.SDN 3.2.0 이상을 사용하는 경우 failOnDuplicate 속성을 사용하십시오.
SDN 3.2.0 이상을 사용하는 경우 failOnDuplicate 속성을 사용하십시오.
@Indexed(unique = true, failOnDuplicate = true)
from https://stackoverflow.com/questions/22362767/spring-data-neo4j-repository-save-and-indexedunique-true by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Framework jar 파일을 다운로드 할 수 없음 (0) | 2019.05.13 |
---|---|
[SPRING] Mockito의 Spy object from Spring (0) | 2019.05.12 |
[SPRING] 속성 자리 표시 자 값으로 @Profile 주석 사용 (0) | 2019.05.12 |
[SPRING] 주석 속성의 값은 상수 표현이어야합니다. (0) | 2019.05.12 |
[SPRING] Spring Batch - TaskletStep에서 건너 뛸 수있는 예외 (0) | 2019.05.12 |