我们正在使用带有存储库方法和注释查询的 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() 。这是为什么?
但是这里做错了什么?
任何帮助表示赞赏!
谢谢!