2

我们正在使用带有存储库方法和注释查询的 spring-data-neo4j。以前,我们使用 SDN 与独立服务器的休息连接。不过性能很差,所以我们决定使用带有嵌入式 neo4j 实例的 SDN。但这并没有按预期工作。

这里有一些类

节点实体

import java.util.Set;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedToVia;

import com.xxx.xyz.relationships.UserToAnnotation;
import com.xxx.xyz.relationships.UserToBookmark;
import com.xxx.xyz.relationships.UserToGroup;
import com.xxx.xyz.relationships.UserToLastReadMedia;
import com.xxx.xyz.relationships.UserToLicenseOwner;
import com.xxx.xyz.relationships.UserToLicenseReader;
import com.xxx.xyz.relationships.UserToUser;

/** Simple user class. */
@NodeEntity
public class Neo4jUser {

    @GraphId
    Long id;

    private String type;

    @Indexed(unique=true)
    private String emailAddress;

    @Indexed
    private String nickname;

    private String passwordHash;

    private String givenName;

    private String familyName;

    private Long birthdate;


    @JsonIgnore
    @RelatedToVia(type = "isIn", direction = Direction.OUTGOING)
    private Set<UserToGroup> memberships;

    public Neo4jUser() {
    }

    //constructor

    //getter / setter


    public void isIn(final Neo4jGroup group, final String role) {
        memberships.add(new UserToGroup(this, group, role));
    }



}

一个关系实体

package com.xxx.xyz.relationships;

import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;

import com.xxx.xyz.model.db.Neo4jGroup;
import com.xxx.xyz.model.db.Neo4jUser;

@RelationshipEntity(type="isIn")
public class UserToGroup {

    @GraphId
    Long id;

    @Fetch @StartNode
    private Neo4jUser user;

    @Fetch @EndNode
    private Neo4jGroup group;

    private String role;

    public UserToGroup(){
    }

    public UserToGroup(final Neo4jUser user, final Neo4jGroup group, final String role)
    {
        this.user = user;
        this.group = group;
        this.role = role;
    }

}

用户存储库

@Transactional
public interface UserRepository extends GraphRepository<Neo4jUser> {

//annotated cypher queries

}

春天应用上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/data/neo4j 
        http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config />
    <context:spring-configured />
    <context:component-scan base-package="com.xxx.xyz.service" />

    <neo4j:config storeDirectory="data/graph.db" />

    <neo4j:repositories base-package="com.xxx.xyz.repository" />


</beans>

maven依赖

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

尝试memberships使用该方法修改集合时,Neo4JUser.isIn()会引发以下异常

org.neo4j.graphdb.NotInTransactionException
    at org.neo4j.kernel.impl.persistence.PersistenceManager.getResource(PersistenceManager.java:252)
    at org.neo4j.kernel.impl.persistence.PersistenceManager.relationshipCreate(PersistenceManager.java:161)
    at org.neo4j.kernel.impl.core.NodeManager.createRelationship(NodeManager.java:252)
    at org.neo4j.kernel.impl.core.NodeImpl.createRelationshipTo(NodeImpl.java:578)
    at org.neo4j.kernel.impl.core.NodeProxy.createRelationshipTo(NodeProxy.java:207)
    at org.springframework.data.neo4j.support.DelegatingGraphDatabase.createRelationship(DelegatingGraphDatabase.java:125)
    at org.springframework.data.neo4j.support.mapping.EntityStateHandler.getOrCreateRelationship(EntityStateHandler.java:168)
    at org.springframework.data.neo4j.support.mapping.EntityStateHandler.useOrCreateState(EntityStateHandler.java:139)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:146)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:249)
    at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
    at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:293)
    at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory$RelatedToViaCollectionFieldAccessor.persistEntities(RelatedToViaCollectionFieldAccessorFactory.java:99)
    at org.springframework.data.neo4j.fieldaccess.RelatedToViaCollectionFieldAccessorFactory$RelatedToViaCollectionFieldAccessor.setValue(RelatedToViaCollectionFieldAccessorFactory.java:93)
    at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.updateValue(ManagedFieldAccessorSet.java:94)
    at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.update(ManagedFieldAccessorSet.java:82)
    at org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet.add(ManagedFieldAccessorSet.java:108)
    at com.xxx.xyz.model.db.Neo4jUser.isIn(Neo4jUser.java:187)

正如我发现做一些研究,SDN的其余连接不使用事务,嵌入式版本使用,所以NotInTransactionException是可能的。

此外,我们没想到save()会在处理带有关系的集合时被触发。之后我们总是手动调用 save() 。这是为什么?

但是这里做错了什么?

任何帮助表示赞赏!

谢谢!

4

1 回答 1

1

这确实有点令人困惑,我也遇到了同样的问题。如果您在模型中使用关系集,则该集将由 SDN 支持。因此,如果您对集合进行任何修改,SDN 将尝试相应地更改您的数据库(即创建/删除关系)。如果你不希望你的模型得到数据库的支持,你应该使用 Iterable。

http://static.springsource.org/spring-data/neo4j/docs/current/reference/htmlsingle/#reference:programming_model:relationships:relatedto

于 2013-09-18T12:24:22.393 回答