如何解决映射关系的两端并保存时,我在 Spring Data Neo4j 中得到不一致的结果
我有一个 User
节点,其中 FRIEND_REQUEST
关系映射到 sentFriendRequestList
列表和 receivedFriendRequestList
列表,如下所示:
@Node
data class User(
@Id
@GeneratedValue(UUIDStringGenerator::class)
var userId: String?,@Relationship(type = "FRIEND_REQUEST",direction = Relationship.Direction.OUTGOING)
var sentFriendRequestList: MutableList<FriendRequest> = mutableListOf(),direction = Relationship.Direction.INCOMING)
var receivedFriendRequestList: MutableList<FriendRequest> = mutableListOf(),var email: String
)
FriendRequest
类:
@RelationshipProperties
data class FriendRequest(
@Id
@GeneratedValue
var friendRequestId: Long?,/**
* Represents the receiver in an OUTGOING relationship and the sender in an INCOMING relationship.
*/
@TargetNode
var friendRequestOtherNode: User
){
constructor(friendRequestOtherNode: User) : this(null,friendRequestOtherNode)
}
保存多个好友请求时,在某些情况下,所有先前创建的关系都会从给定节点中消失,而只会出现新创建的关系。
我是这样保存的:
fun saveFriendRequest(sender: User,receiver: User) {
val sentFriendRequest = FriendRequest(receiver)
val receivedFriendRequest = FriendRequest(sender)
sender.sentFriendRequestList.add(sentFriendRequest)
receiver.receivedFriendRequestList.add(receivedFriendRequest)
userRepository.save(sender)
userRepository.save(receiver)
}
我不明白问题出在哪里,尤其是因为有时它运行无故障。
我在我的 GitHub 上创建了一个小型测试项目:link。它包含数据结构和可以立即运行的测试类。测试显示了同样的问题,多次运行后它可能失败也可能成功。
解决方法
我有点不确定正确的查询,但是您的自定义 Cypher 语句不会返回所有朋友和关系以获得更深层次的链接。 改为:
MATCH (user:User{email: \$email})
OPTIONAL MATCH path=(user)-[:FRIEND_REQUEST*]-(friend:User)
WITH user,friend,relationships(path) as friend_requests
RETURN user,collect(friend_requests),collect(distinct(friend))
为我解决了这个问题(或者十次测试运行只是随机绿色)。
另一种解决方案是,为了避免自定义查询,定义 findByEmail(email: String): User
并让 Spring Data Neo4j 创建查询。
出现的问题是
First operation:
frodo -> sam
sam -> frodo
Second operation:
frodo -> bilbo
bilbo -> frodo
Sam 的结果类似于 sam-frodo-bilbo
。
当您加载 Frodo 或 Bilbo 时,关系并未完全与 Sam 水合。
当您保存 Bilbo(或 Frodo)时,SDN 将遍历所有关系,最终找不到 Sam 关系。因为它是空的,SDN会在保存时删除关系。
我在您的代码中看到的另一个问题:
您绝对应该使用 @PersistenceConstructor
注释手动定义的构造函数,因为 Kotlin 创建了一个不可见的复制构造函数,而 Spring Data 通常不知道选择哪个。所以你可能会随机遇到复制构造函数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。