gpt4 book ai didi

Spring Data Neo4j -repository.save 和 @Indexed(unique=true)

转载 作者:行者123 更新时间:2023-12-02 08:21:39 27 4
gpt4 key购买 nike

今天我尝试了 Spring Data Neo4j,我终于不知何故让它工作了...

我正在使用:

  • Spring 4.0.2
  • Spring Data Neo4j 3.0.0
  • QueryDSL 3.3.1
  • Neo4j 2.0.1

这是我的配置:

@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> {}
<小时/>

我可以在数据库中成功创建一个用户,然后通过以下方式检索它:

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) String email,它只是覆盖数据库中的对象。

并且:如果我尝试使用不同的电子邮件值创建第二个用户,旧用户将被覆盖。

创建代码非常简单:

User u = new User();
u.setEmail("some@email-address.com");
repo.save(u);

我还尝试使用 Neo4j 的独立版本而不是嵌入式版本,结果完全相同。在 webadmin View 中我可以看到它创建了一些索引:

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:

如果我访问网络管理员并简单执行两次:

CREATE (n:User {email:'test@mail.com'})

我收到一个错误。所以我的Java代码或SDN一定有问题......

<小时/>

更新#3:

Spring Data 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

如何解决此问题?我想要一个异常(exception)。

<小时/>

更新#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", "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);

这样它就按预期工作了,至少我得到了一个异常(exception):

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

但现在我不知道如何将其与 Spring Data Repository 集成......

最佳答案

如果您使用 SDN 3.2.0+,请使用failOnDuplicate 属性:

@Indexed(unique = true, failOnDuplicate = true)

关于Spring Data Neo4j -repository.save 和 @Indexed(unique=true),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22362767/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com