当前位置: 首页 > 知识库问答 >
问题:

如何更新spring-data-neo4j中的relationship属性?

陈哲
2023-03-14

我构建了一个使用spring数据的项目,并成功地创建了实体,添加了与属性的关系。除了更新关系属性值之外,所有这些属性值都运行得很好,在它们被持久化之后。

为了探索它,我合并了SpringData文档中的简单“Worlds”示例,并对其进行了一点增强。在这个例子中,有一个与其他世界相关的世界实体。我在这个关系中添加了一个名为“YearstoReach”的属性。

在我的测试中,我创建了两个世界:火星和地球,并将年可达性设置为10。然后,我调用WorldRepositoryService.UpdateYearStoOtherWorld,并将yearsToReach设置为20。这个方法以第一个世界的一个'save'结束,但是当再次查询世界时,它似乎并没有实际改变数据库中的值。

也许真的很简单,但我只是花了几个小时想弄清楚我做错了什么...

这是我的代码,我去掉了一些不相关的部分。我非常感谢任何响应/代码示例。

这是我的“World”实体(注意:“BaseWorld”类未标记为@NodeEntity,它只包含“Name”属性)。


    @NodeEntity
    @Getter
    @Setter
    public class World extends BaseWorld {

        @GraphId
        private Long id;

        @RelatedToVia(type = OtherWorldRelationship.RELATIONSHIP_TYPE, direction = Direction.OUTGOING, elementClass = OtherWorldRelationship.class)
        private Set reachableByRocket = new HashSet();


        public void addRocketRouteTo(World otherWorld, int yearsToReach) {
            OtherWorldRelationship otherWorldRelationship = new OtherWorldRelationship();
            otherWorldRelationship.setWorld(this);
            otherWorldRelationship.setOtherWorld(otherWorld);
            otherWorldRelationship.setYearsToReach(yearsToReach);
            reachableByRocket.add(otherWorldRelationship);
        }

        public void updateYearsToOtherWorld(World otherWorld, int years) {
            Iterator otherWorlds = reachableByRocket.iterator();
            while (otherWorlds.hasNext() )
            {
                OtherWorldRelationship otherWorldRelationship = otherWorlds.next();
                if (otherWorld.getName().equals(otherWorldRelationship.getOtherWorld().getName())){
                    otherWorldRelationship.setYearsToReach(years);
                    break;
                }
            }
        }

这是关系类:


    @RelationshipEntity
    @Getter
    @Setter
    public class OtherWorldRelationship {
        public static final String RELATIONSHIP_TYPE = "OtherWorld";

        @GraphId
        Long id;

        @StartNode
        private World world;

        @EndNode
        private World otherWorld;

        private int yearsToReach;

    }

这是WorldRepository接口-它仅从GraphRepository继承


    public interface WorldRepository extends GraphRepository, NamedIndexRepository {
    }

这是WorldRepositoryService:


    @Repository
    public class WorldRepositoryService implements IWorldRepositoryService {

        @Getter
        @Setter
        @Autowired
        private WorldRepository worldRepository;

        @Override
        @Transactional
        public Collection createSomeWorlds() {
            ArrayList newWorlds = new ArrayList();
            World earth = createWorld("Earth");
            newWorlds.add(earth);

            World mars = createWorld("Mars");
            mars.addRocketRouteTo(earth, 10);
            newWorlds.add(mars);

            return newWorlds;
        }

        @Override
        @Transactional
        public World createWorld(String name) {
            return worldRepository.save(new World(name));
        }

        @Override
        public World findWorldNamed(String name) {
            return worldRepository.findByPropertyValue("name", name);
        }


        @Override
        @Transactional
        public World updateYearsToOtherWorld(World mars, World earth, int years) {
            mars.updateYearsToOtherWorld(earth, years);
            return worldRepository.save(mars);
        }

    }

最后,这些是我的测试中的行:


    @Test
        public void testNeo4JRelationshipUpdateData() {

            Iterable worlds = worldRepositoryService.createSomeWorlds();//Mars and Earth

            World earth = worldRepositoryService.findWorldNamed("Earth");
            World mars =  worldRepositoryService.findWorldNamed("Mars");

            Integer distanceInYears = mars.getYearsToOtherWorld(earth);
            System.out.println("Distance beteween Mars and " + distanceInYears);
            Assert.assertEquals(10, distanceInYears.intValue());

            mars = worldRepositoryService.updateYearsToOtherWorld(mars, earth, 20);

            System.out.println("Distance beteween Mars and Earth: " + distanceInYears);
            Assert.assertEquals(20, distanceInYears.intValue());

            mars = worldRepositoryService.findWorldNamed("Mars");
            distanceInYears = mars.getYearsToOtherWorld(earth);
            System.out.println("Distance beteween Mars and Earth after update: " + distanceInYears);

            // !!! This line fails - it gets 10 instead of 20 !!! //
            Assert.assertEquals(20, distanceInYears.intValue());

        }

共有2个答案

公孙锋
2023-03-14

您确定是最后一个断言失败了吗?第二个可能会失败--更新后您不会读取distanceInYears变量。

范侯林
2023-03-14

感谢jjaderberg的帮助--我是为了别人而粘贴解决方案的:

解决方法是保存关系本身,而不是保存它的实体。这是固定代码:

我为关系定义了新的存储库接口:


    public interface OtherWorldRelationshipRepository extends GraphRepository, NamedIndexRepository {

    }

在WorldRepositoryService.clas中,我保存了关系而不是实体:


    @Override
        @Transactional
        public OtherWorldRelationship updateYearsToOtherWorld(World mars, World earth, int years) {
            OtherWorldRelationship yearsToOtherWorldRelation = mars.updateYearsToOtherWorld(earth, years);
            return otherWorldRelationshipRepository.save(yearsToOtherWorldRelation);
        }

就这样!!希望它能像帮助我自己一样帮助别人。

卡梅尔

 类似资料:
  • 对于具有任何属性(已索引或未索引)的NodeEntity,由于某些用例,我希望将数据类型从Integer更改为String 我只是更改了定义的NodeEntity类中的数据类型。新数据成功插入数据库,属性的数据类型为新设置的数据类型(即String)。但是,在此更改之前,数据库中已存在的节点的属性数据类型仍保持为旧数据类型(即整数) 有没有办法修改数据库中所有节点的数据类型?

  • Spring Data Neo4J 提供高级特性,将批注的实体类映射到的 Neo4j 图形数据库。它的模块化编程模型相当于知名的 Spring 模块,建立了与图形交互的基础,并且可用于先进储存库支持。Spring Data Neo4j 是 Spring Data 项目的一部分,目标是向 NoSQL 数据库提供便捷支持。

  • 我无融资创业新项目访问Neo4j数据与REST的例子。该示例使用嵌入式数据库,而不是独立的neo4j服务器,但我希望使用Neo4J webadmin界面来可视化我的数据。如何从此配置开始启用webadmin接口? (他们让WrappingNoServerBootstrapper与spring-data-neo4j一起使用WrappingNoServerBootstrapper,但答案中遗漏了很多知

  • 问题内容: 我正在从“ 使用REST访问Neo4j数据”示例中引导一个新项目。该示例使用嵌入式数据库而不是独立的neo4j服务器,但是我想使用Neo4J Webadmin界面来可视化我的数据。如何从此配置开始启用Webadmin界面? (他们让WrappingNeoServerBootstrapper与spring-data-neo4j一起使用WrappingNeoServerBootstrapp

  • 问题内容: 我有一个应用程序,它使用MySQL和通过REST的Neo4j服务器版本执行一些批处理作业。 我无法弄清楚如何使它们正确地协同工作:我可以使它们两个同时工作,但不能同时工作。我发现的帖子并非特定于Neo4j的服务器版本,也许就是问题所在,因为其他一切对我来说似乎都不错。 我的配置: JpaConfig Neo4j.xml 通过这种配置,Mysql可以完美工作,但是Neo4j不会将任何属性

  • 假设我从存储库中查找一个对象。如果在查找后立即保存此对象,则Spring数据足够聪明,不会更新数据库。如果我更改此对象中的属性,然后保存,则spring数据会进行更新。它如何知道是否需要进行更新?