编辑:github上可用的示例项目。
我在我们的后端项目中使用Neo4J(Rest图形数据库,托管在grapheneDb中)和Spring Data。
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase">
我在两个实体之间有一个简单的一对多关系:User
和Stay
。
编辑:我认为这与此问题无关,但在SDN4中看到similar problem之后,我想我需要更新问题(有一个基本的{{ 1}}类,两个实体都在扩展这个基类。)
@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.
}
正确检索用户修改。
UserRepository
注意:我也尝试通过存储库界面而不是Neo4jTemplate存储,但我遇到了同样的问题。
两个实体都正确保存在neo4j数据库中,这只是一个持久性问题。
我认为这应该很容易,所以我可能会遗漏一些东西..
非常感谢任何帮助。
相关版本:
public interface UserRepositoryCustom {}
public interface UserRepository extends GraphRepository<User>, UserRepositoryCustom {
User findById(String id);
}
User user = userRepository.findById(userId);
还有另一个SO question有一个非常类似的问题,但到目前为止没有回复。
答案 0 :(得分:2)
这是一个棘手的事情。
你的自定义等于方法会导致两个设置了node-id但尚未设置uuid-id的实体相等,这样当它们加载到一个集合中时,该集合将只包含一个
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,而不是周五发布的。{/ p>