当Map关系的两端并保存它时,我在spring数据neo4j中得到了不一致的结果

vi4fp9gy  于 2021-07-22  发布在  Java
关注(0)|答案(1)|浏览(323)

我有一个 User 具有的节点 FRIEND_REQUEST Map到 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(),

    @Relationship(type = "FRIEND_REQUEST", 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上创建了一个小测试项目。它包含数据结构和一个可以立即运行的测试类。测试显示了同样的问题,在多次运行之后,它可能失败,也可能成功。

m0rkklqb

m0rkklqb1#

我对正确的查询有点不确定,但是您的自定义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数据通常不知道该选择哪个。所以您可能会随机遇到复制构造函数。

相关问题