spring-data-neo4j基本的一对多关系不会持续存在

编辑 : github上提供的示例项目。

我在我们的后端项目中使用Neo4J(Rest图形数据库,托管在grapheneDb中)和Spring Data。

 

我在两个实体之间有一个简单的一对多关系: UserStay

编辑 :我认为这与该问题无关,但在SDN4中看到类似问题之后,我认为我需要更新问题(有一个基本的@NodeEntity类,两个实体都在扩展这个基类)。

 @NodeEntity public abstract class BasicNodeEntity implements Serializable { @GraphId private Long nodeId; } public class User extends BasicNodeEntity { @RelatedTo(type = "HAS_STAY", direction = Direction.OUTGOING) Set stays; public void addStay(Stay stay) { stays.add(stay); } } public class Stay extends BasicNodeEntity { @RelatedTo(type = "HAS_STAY", direction = Direction.INCOMING) User user; } 

我不能坚持不止一次。 我添加给用户的第一次停留是正确的,但只是第一次。 添加的下一个留下永远不会持续,我总是检索第一个。

我用来创建新住宿的方法是:

  @Autowired Neo4jOperations template; @Transactional private void createStay(Stay stay, User user) throws Exception { stay = template.save(stay); user.addStay(stay); template.save(user); // If i evaluate user at this point, it contains both stays // But if I retrieve the user from the repository, it just contains // the first stay, the second one has not persisted. } 

编辑 :通过UserRepository正确检索用户修改。

 public interface UserRepositoryCustom {} public interface UserRepository extends GraphRepository, UserRepositoryCustom { User findById(String id); } User user = userRepository.findById(userId); 

注意:我也试图通过存储库接口而不是Neo4jTemplate保存,但我有同样的问题。

两个实体都正确保存在neo4j数据库中,这只是一个持久性问题。

我觉得这应该很容易,所以我可能会遗漏一些东西……

任何帮助将不胜感激。

相关版本:

 4.0.5.RELEASE 3.3.2.RELEASE 

还有另外一个问题, 问题非常相似,但到目前为止还没有回应。

这是一个棘手的事情。

您的自定义equals方法会导致两个实例的node-id设置但尚未设置uuid-id,因此在将它们加载到集合中时,该集合将只包含一个。

代码:RelationshipHelper

 protected Set createEntitySetFromRelationshipEndNodes(Object entity, final MappingPolicy mappingPolicy, final Class relatedType) { final Iterable nodes = getStatesFromEntity(entity); final Set result = new HashSet(); for (final Node otherNode : nodes) { Object target = template.createEntityFromState(otherNode, relatedType, mappingPolicy); result.add(target); } return result; } 

如果您将代码更改为在BasicNode实体中具有等号/哈希码:

  @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof BasicNodeEntity)) return false; BasicNodeEntity that = (BasicNodeEntity) o; if (nodeId != null) { if (!nodeId.equals(that.nodeId)) return false; } else { if (that.nodeId != null) return false; } return true; } @Override public int hashCode() { return nodeId != null ? nodeId.hashCode() : 0; } 

这样只有nodeId集的实体才具有可比性

并适应子类方法

  @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof IdentifiableEntity)) return false; IdentifiableEntity entity = (IdentifiableEntity) o; //change if (!super.equals(o)) return false; if (id != null) { if (!id.equals(entity.id)) return false; } else { if (entity.id != null) return false; } return true; } @Override public int hashCode() { //change if (super.hashCode() != 0) return super.hashCode(); return id != null ? id.hashCode() : 0; } 

然后它工作。

如果您正在使用Neo4j服务器,那么我建议您查看周五发布的SDN 4 RC2 。