【问题标题】:spring-data-neo4j basic one-to-many relationship not persistingspring-data-neo4j 基本的一对多关系不持久
【发布时间】:2015-11-04 01:35:37
【问题描述】:

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

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

<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase">

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

编辑:我认为这与问题无关,但在 SDN4 中看到 similar problem 后,我想我需要更新问题(有一个基本的 @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<Stay> 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.
   }

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

public interface UserRepositoryCustom {}

public interface UserRepository extends GraphRepository<User>, UserRepositoryCustom {    
   User findById(String id);
}

User user = userRepository.findById(userId);

注意:我也尝试通过存储库界面而不是 Neo4jTemplate 进行保存,但我遇到了同样的问题。

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

我认为这应该很容易,所以我可能遗漏了一些东西..

任何帮助将不胜感激。

相关版本:

<spring.version>4.0.5.RELEASE</spring.version>
<spring-data-neo4j.version>3.3.2.RELEASE</spring-data-neo4j.version>

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

【问题讨论】:

  • 您从哪里获得您添加住宿的用户?它是否已经在收藏中首次停留?
  • 您使用的是嵌入式还是 Neo4j 服务器?
  • 但撑杆是两种不同的撑杆?您认为您可以为此设置创建一个小型测试用例吗?
  • 嗨,迈克尔。我创建了一个带有错误的示例project on github。我希望这可以帮助你。感谢您的宝贵时间!
  • 嗨@MichaelHunger!您有机会查看示例项目吗?如果示例不够清楚,请告诉我。再次感谢

标签: java neo4j spring-data spring-data-neo4j


【解决方案1】:

这是一件棘手的事情。

您的 自定义 equals 方法 使两个已设置其节点 ID 但尚未设置其 uuid-id 的实体相等,以便在将它们加载到一个集合时,该集合将只包含一个.

代码在:RelationshipHelper

protected Set<Object> createEntitySetFromRelationshipEndNodes(Object entity, final MappingPolicy mappingPolicy, final Class<?> relatedType) {
    final Iterable<Node> nodes = getStatesFromEntity(entity);
    final Set<Object> result = new HashSet<Object>();
    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,而不是在周五发布。

【讨论】:

  • 非常感谢迈克尔,完美的收获!我无法指出正确的方向。我已经在我们的项目中尝试过,它就像一个魅力。我们已经计划切换到 SDN4,感谢您的建议。
猜你喜欢
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多