【问题标题】:Spring-Neo4j: Relationship is not retrieving correctlySpring-Neo4j:关系检索不正确
【发布时间】:2019-03-14 16:02:50
【问题描述】:

我有一个实体类,它把自己称为父类。

@NodeEntity
public class Config {

    @Id 
    @GeneratedValue 
    private Long id;

    @Relationship(type = "OVERRIDES", direction="INCOMING")
    private Config parentConfig;

    @Properties(allowCast=true, prefix="properties", delimiter=".")
    private Map<String, String> properties;
    ....
}

当我在我的 java 代码中运行内置的 findById() 方法时,“parentConfig”始终与子对象相同。我从来没有看到关系的另一端。我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    这可以按预期工作,但取决于您希望如何为您的配置建模。

    假设您想表达“子级覆盖父级配置”,我将其建模为

    CREATE (c:Config {name: 'Parent'}) <- [:OVERRIDES] - (c2:Config {name: 'Child'})
    

    这给了你:

    然后您必须将关联建模为从子对象传出,如下所示:

    import org.neo4j.ogm.annotation.GeneratedValue;
    import org.neo4j.ogm.annotation.Id;
    import org.neo4j.ogm.annotation.Relationship;
    
    public class Config {
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
    
        @Relationship(type = "OVERRIDES", direction = Relationship.OUTGOING)
        private Config parent;
    
        public Long getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Config getParent() {
            return parent;
        }
    
        @Override public String toString() {
            return "Config{" +
                "name='" + name + '\'' +
                '}';
        }
    }
    

    把它变成一个完整的例子:

    import java.util.Optional;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.neo4j.repository.Neo4jRepository;
    import org.springframework.stereotype.Component;
    
    interface ConfigRepo extends Neo4jRepository<Config, Long> {
        Optional<Config> findOneByName(String name);
    }
    
    @Component
    class Example implements CommandLineRunner {
    
        @Autowired
        private ConfigRepo configRepo;
    
        @Override
        public void run(String... args) throws Exception {
            configRepo.findOneByName("Parent").ifPresent(c -> {
                System.out.println("Config " + c + " has parent " + c.getParent());
            });
    
            configRepo.findOneByName("Child").ifPresent(c -> {
                System.out.println("Config " + c + " has parent " + c.getParent());
            });
        }
    }
    
    @SpringBootApplication
    public class SorecassocApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SorecassocApplication.class, args);
        }
    }
    

    会回来

    2018-10-10 09:20:21.960  INFO 3832 --- [           main] o.n.o.drivers.bolt.request.BoltRequest   : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)-[r_o1:`OVERRIDES`]->(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Parent}
    Config Config{name='Parent'} has parent null
    2018-10-10 09:20:21.984  INFO 3832 --- [           main] o.n.o.drivers.bolt.request.BoltRequest   : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)-[r_o1:`OVERRIDES`]->(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Child}
    Config Config{name='Child'} has parent Config{name='Parent'}
    

    如果从孩子的角度将关系建模为 INCOMING,则必须反转节点中的关系。否则输出为:

    2018-10-10 09:22:54.929  INFO 3837 --- [           main] o.n.o.drivers.bolt.request.BoltRequest   : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)<-[r_o1:`OVERRIDES`]-(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Parent}
    Config Config{name='Parent'} has parent Config{name='Child'}
    2018-10-10 09:22:54.951  INFO 3837 --- [           main] o.n.o.drivers.bolt.request.BoltRequest   : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)<-[r_o1:`OVERRIDES`]-(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Child}
    Config Config{name='Child'} has parent null
    

    以下是将示例转换为正在运行的应用程序的依赖项:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.example</groupId>
        <artifactId>sorecassoc</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>sorecassoc</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-neo4j</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    如果这能解决您的问题,请告诉我。

    【讨论】:

    • 谢谢,这很接近!我现在确实得到了 parentConfig,但只升级了一级。我需要在某处指定深度吗?
    • 是的。我们默认将深度限制为 1。添加一个 int 类型的参数,并在上面的示例中使用 @Depth 对其进行注释,并以所需的深度调用它。许多预定义的 Finder 方法已经默认拥有它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多