【问题标题】:How can I update node or node entity in Spring data neo4j?如何在 Spring data neo4j 中更新节点或节点实体?
【发布时间】:2013-03-18 12:54:27
【问题描述】:

在 Spring 数据 neo44 中,我们只有 repository.save(entity),但例如当我的 UserEntity 的属性(电子邮件)更改时,我不知道如何更新。

我也尝试使用 neo4j 模板,但使用现有节点 ID 保存实体导致以下回滚。

org.springframework.dao.InvalidDataAccessApiUsageException: New value must be a Set, was: class java.util.ArrayList; nested exception is java.lang.IllegalArgumentException: New value must be a Set, was: class java.util.ArrayList
    at org.springframework.data.neo4j.support.Neo4jExceptionTranslator.translateExceptionIfPossible(Neo4jExceptionTranslator.java:43)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

我们如何更新节点或节点实体?

public void updateUserNode(UserEntity user) {  
    try{ 
    UserEntity updatedUser = this.getUserByUserId(user.getUserId());//finding node with user id///
    updatedUser.setEmail(user.getEmail());
    updatedUser.setImageId(user.getImageId());
    updatedUser.setFirstname(user.getFirstname());
    updatedUser.setLastname(user.getLastname());
    //System.out.println("Deleting ");
    //userRepository.delete(del);
    System.out.println("UPDATING ");     
    // with existing Id, you can not save it again/, or update
    updatedUser = userRepository.save(updatedUser);
    }catch(Exception e){
      e.printStackTrace();
    }
    //return 
  }

【问题讨论】:

  • 你能分享一下你的User对象的定义吗?

标签: java neo4j spring-data-neo4j


【解决方案1】:

您必须在事务中嵌入 .save()。

举个例子:

final org.neo4j.graphdb.Transaction tx = this.neoTemplate.getGraphDatabaseService().beginTx();
try {
    updatedUser = userRepository.save(updatedUser);
    tx.success();
} finally {
    tx.finish();
}

【讨论】:

  • 你的意思是什么保存也可以更新实体,如果它有图形ID?
  • 你的意思是什么实体通过保存也可以在传递图形ID时更新?实际上 Spring 需要事务,我的 Spring bean 是事务性的,并且成功保存。
  • 我不明白你的问题(我在独立模式下使用 spring-data-neo4j,所以没有 spring 框架)。无论如何,你看过static.springsource.org/spring-data/data-neo4j/docs/… 了吗?有使用spring-data-neo4j的例子
  • 是的,我阅读了文档,但我的问题是您已经在哪里创建了实体和关系,以及当用户更改作为实体属性的电子邮件时,我如何更新 @Node 实体。保存操作失败。
【解决方案2】:

在您的UserEntity 域对象中,您是否存储了任何关系?确保它们被声明为 Set<T> 而不是 Iterable<T>

发件人:http://static.springsource.org/spring-data/data-graph/snapshot-site/reference/html/#reference:programming_model:relationships:relatedto

"也可以有引用一组节点的字段 实体 (1:N)。这些字段有两种形式,可修改或 只读。可修改字段是 Set 类型,并且是只读的 字段是可迭代的,其中 T 是 @NodeEntity 注释的类。”

我怀疑你的默认构造函数正在实例化一个 ArrayList...

【讨论】:

  • NodeEntity 公共类 UserEntity 实现 Serializable { private static final long serialVersionUID = 1L;公共静态最终字符串朋友=“朋友”; GraphId 私有长id; Indexed(unique = true) private Long userId;私人字符串电子邮件; Fetch RelatedTo(elementClass = UserEntity.class, type = FRIEND, direction = Direction.OUTGOING) private List friendsList;
  • 我只有@Fetch @RelatedTo(elementClass = UserEntity.class, type = FRIEND, direction = Direction.OUTGOING) private List friendsList;
  • 是的,这是你的问题。列表在关系的上下文中没有意义,因为它们在图中总是无序的。 en.wikipedia.org/wiki/Graph_(mathematics)#Graph 请将 List 替换为 Set:@Fetch @RelatedTo(elementClass = UserEntity.class, type = FRIEND, direction = Direction.OUTGOING) private Set<UserEntity> friendsList;
  • 嗨,谢谢,我将 List 替换为 Set,现在一切正常,只是在前端我将数据从 Set 填充到 ArrayList,因为我需要可迭代类型。谢谢
【解决方案3】:

由于您使用的是 SDN,因此您永远不需要手动启动/提交任何事务。

假设你的 User 类看起来像这样

@NodeEntity(label="User)
public class User extends DomainObject{
    @Property(name = "email")
    private String email;

    //getter and setter
}

而您的UserRepository 与此类似:

public interface UserRepository extends GraphRepository<User> {

    //maybe this is already right at hand by SDN and thus redundant?
    @Query("MATCH (u:User {email:{email}}")
    public User findByEmail(@Param("email") String email)
}

那么你可以在UserService 类上使用@Transactional

@Component
@Transactional
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public void updateEmail(String email) {
        User user = userRepository.findByEmail(email);
        if (user == null) return; //or throw...
        user.setEmail(email);
        userRepository.save(user);
    }
}

【讨论】:

    猜你喜欢
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    相关资源
    最近更新 更多