0

我已经建立了一个使用 spring-data 并成功创建实体、添加与属性的关系的项目。除了更新关系属性值外,一切似乎都运行良好,一旦它们被持久化。

为了尝试探索它,我合并了 SpringData 文档中的简单“世界”示例并对其进行了一些改进。在此示例中,有一个与其他世界相关的 World 实体。我在这种关系中添加了一个名为“yearsToReach”的属性。

在我的测试中,我创建了两个世界:火星和地球,并将 yearsToReach 设置为 10。然后,我调用 WorldRepositoryService.updateYearsToOtherWorld 并将 yearsToReach 设置为 20。此方法以第一个 World 的“保存”结束,但在查询再次世界,它似乎并没有真正改变数据库中的值。

也许这真的很简单,但我只是花了几个小时试图找出我做错了什么......

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

这是我的“世界”实体(注意:“BaseWorld”类未标记为@NodeEntity,它仅包含“名称”属性)。

    @NodeEntity
    @Getter
    @Setter
    公共类 World 扩展 BaseWorld {

        @GraphId
        私人长ID;

        @RelatedToVia(type = OtherWorldRelationship.RELATIONSHIP_TYPE, direction = Direction.OUTGOING, elementClass = OtherWorldRelationship.class)
        私有 SetreachableByRocket = new HashSet();


        公共无效 addRocketRouteTo(世界其他世界,int yearsToReach){
            OtherWorldRelationship otherWorldRelationship = new OtherWorldRelationship();
            otherWorldRelationship.setWorld(this);
            otherWorldRelationship.setOtherWorld(otherWorld);
            otherWorldRelationship.setYearsToReach(yearsToReach);
            reachableByRocket.add(otherWorldRelationship);
        }

        public void updateYearsToOtherWorld(世界其他世界,整数年){
            迭代器 otherWorlds = reachableByRocket.iterator();
            而 (otherWorlds.hasNext() )
            {
                其他世界关系 otherWorldRelationship = otherWorlds.next();
                if (otherWorld.getName().equals(otherWorldRelationship.getOtherWorld().getName())){
                    otherWorldRelationship.setYearsToReach(年);
                    休息;
                }
            }
        }

这是关系类:

    @RelationshipEntity
    @Getter
    @Setter
    公共类 OtherWorldRelationship {
        public static final String RELATIONSHIP_TYPE = "OtherWorld";

        @GraphId
        长身份证;

        @StartNode
        私人世界世界;

        @EndNode
        私人世界另一个世界;

        私人 int yearsToReach;

    }

这是 WorldRepository 接口- 它只继承自 GraphRepository

    公共接口 WorldRepository 扩展 GraphRepository,NamedIndexRepository {
    }

这是WorldRepositoryService

    @Repository
    公共类 WorldRepositoryService 实现 IWorldRepositoryService {

        @Getter
        @Setter
        @自动连线
        私有世界存储库世界存储库;

        @覆盖
        @Transactional
        公共集合 createSomeWorlds() {
            ArrayList newWorlds = new ArrayList();
            世界地球 = createWorld("地球");
            newWorlds.add(地球);

            世界火星 = createWorld("火星");
            mars.addRocketRouteTo(地球, 10);
            newWorlds.add(火星);

            返回新世界;
        }

        @覆盖
        @Transactional
        公共世界创建世界(字符串名称){
            return worldRepository.save(new World(name));
        }

        @覆盖
        公共世界findWorldNamed(字符串名称){
            return worldRepository.findByPropertyValue("name", name);
        }


        @覆盖
        @Transactional
        public World updateYearsToOtherWorld(世界火星,世界地球,整数年){
            mars.updateYearsToOtherWorld(地球,年);
            返回 worldRepository.save(mars);
        }

    }

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

    @测试
        公共无效 testNeo4JRelationshipUpdateData() {

            Iterable worlds = worldRepositoryService.createSomeWorlds();//火星和地球

            世界地球 = worldRepositoryService.findWorldNamed("地球");
            世界火星 = worldRepositoryService.findWorldNamed("Mars");

            整数距离InYears = mars.getYearsToOtherWorld(earth);
            System.out.println("火星到" + distanceInYears);
            Assert.assertEquals(10, distanceInYears.intValue());

            火星 = worldRepositoryService.updateYearsToOtherWorld(火星,地球,20);

            System.out.println("火星与地球的距离:" + distanceInYears);
            Assert.assertEquals(20, distanceInYears.intValue());

            mars = worldRepositoryService.findWorldNamed("Mars");
            distanceInYears = mars.getYearsToOtherWorld(地球);
            System.out.println("更新后火星与地球的距离:" + distanceInYears);

            // !!! 这条线失败了 - 它得到 10 而不是 20 !!! //
            Assert.assertEquals(20, distanceInYears.intValue());

        }

4

3 回答 3

4

感谢 jjaderberg 的帮助 - 为了其他人,我正在粘贴解决方案:

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

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

    公共接口 OtherWorldRelationshipRepository 扩展 GraphRepository,NamedIndexRepository {

    }

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

    @覆盖
        @Transactional
        public OtherWorldRelationship updateYearsToOtherWorld(世界火星,世界地球,整数年){
            OtherWorldRelationship yearsToOtherWorldRelation = mars.updateYearsToOtherWorld(earth, years);
            返回 otherWorldRelationshipRepository.save(yearsToOtherWorldRelation);
        }

而已!!希望它帮助别人,因为它帮助了我自己。

卡梅尔

于 2013-11-12T06:41:05.843 回答
0

你是完全正确的 - 我忘了重新阅读“distanceInYears”。不幸的是,这并不能解决问题......该值仍然是 10。两个断言都失败(如果我评论第一个,另一个我试图再次检索“Mars”的断言 - 也失败)。

正确的测试代码如下所示:

    @测试
        公共无效 testNeo4JRelationshipUpdateData() {

            worldRepositoryService.deleteAll();

            Iterable worlds = worldRepositoryService.createSomeWorlds();//火星和地球

            世界地球 = worldRepositoryService.findWorldNamed("地球");
            世界火星 = worldRepositoryService.findWorldNamed("Mars");

            整数距离InYears = mars.getYearsToOtherWorld(earth);
            System.out.println("火星到" + distanceInYears);
            Assert.assertEquals(10, distanceInYears.intValue());

            火星 = worldRepositoryService.updateYearsToOtherWorld(火星,地球,20);
            distanceInYears = mars.getYearsToOtherWorld(地球);

            /* 这是失败的断言:*/
            System.out.println("火星与地球的距离:" + distanceInYears);
            Assert.assertEquals(20, distanceInYears.intValue());

            /* 如果我们注释前两行,这一行也会失败:*/
            mars = worldRepositoryService.findWorldNamed("Mars");
            distanceInYears = mars.getYearsToOtherWorld(地球);
            System.out.println("更新后火星与地球的距离:" + distanceInYears);
            Assert.assertEquals(20, distanceInYears.intValue());

        }

于 2013-11-11T07:18:40.357 回答
0

你确定这是最后一个失败的断言吗?似乎第二个应该失败-更新后您没有读取 distanceInYears 变量。

于 2013-11-08T18:51:17.957 回答