A.v
A.v

Reputation: 744

Querying data from Neo4j using spring data returns null all the time

I am trying to use neo4j using spring boot and spring data. I have stored data in my neo4j already and all my queries are returning null unless I store the data using my app which kind of made me confused. I thought maybe I am using an embedded database but I guess that is not the case as I don't have it on my dependencies. Here is my pom.xml:

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.neo4j</groupId>
    <artifactId>neo4jpoc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <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.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
        </dependency>

        <!-- add this dependency if you want to use the bolt driver -->
        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-bolt-driver</artifactId>
        </dependency>

        <!-- add this dependency if you want to use the HTTP driver -->
        <!--<dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-http-driver</artifactId>
        </dependency>-->

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Here is my application.properties:

spring.data.neo4j.uri=bolt://localhost:7687
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=neo4j
logging.level.org.neo4j.driver.GraphDatabase = debug
logging.level.org.neo4j.driver.Driver = debug
logging.level.org.neo4j.driver.OutboundMessageHandler = debug
logging.level.org.neo4j.driver.InboundMessageDispatcher = debug

Here is my db.properties:

URI=bolt://localhost
username=neo4j
password=neo4j

Here is my entity:

package me.neo4j.neo4jpoc.graph.entity;

import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;
import org.neo4j.ogm.annotation.Relationship;

import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@NodeEntity
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Property(name = "NAME")
    private String name;

    @Relationship(type = "CONSISTS_OF", direction = Relationship.UNDIRECTED)
    public Set<MyEntity> children;

    @Relationship(type = "BELONGS_TO", direction = Relationship.UNDIRECTED)
    public Set<MyEntity> parents;

    public void consistsOf(MyEntity child) {
        if (children == null) {
            children = new HashSet<>();
        }
        children.add(child);
    }

    public void belongsTo(MyEntity parent) {
        if (parents == null) {
            parents = new HashSet<>();
        }
        parents.add(parent);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return this.name + "'s children => "
                + Optional.ofNullable(this.children).orElse(
                Collections.emptySet()).stream()
                .map(MyEntity::getName)
                .collect(Collectors.toList()) + "'s parents => "
                + Optional.ofNullable(this.parents).orElse(
                Collections.emptySet()).stream()
                .map(MyEntity::getName)
                .collect(Collectors.toList());
    }
}

Here is my spring data repository:

package me.neo4j.neo4jpoc.graph.repo;

import me.neo4j.neo4jpoc.graph.entity.MyEntity;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.repository.CrudRepository;

public interface MyEntityRepository extends CrudRepository<MyEntity, Long> {

    @Query("MATCH (l:MAIN) RETURN l")
    MyEntity findQuery();
}

Here is my spring boot configuration:

package me.neo4j.neo4jpoc;

import org.neo4j.ogm.config.ClasspathConfigurationSource;
import org.neo4j.ogm.config.ConfigurationSource;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableNeo4jRepositories(basePackages = "me.neo4j.neo4jpoc.graph.repo")
@EnableTransactionManagement
public class Neo4jConfiguration {

    @Bean
    public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory) {
        return new Neo4jTransactionManager(sessionFactory);
    }

    @Bean
    public SessionFactory sessionFactory(org.neo4j.ogm.config.Configuration configuration) {
        // with domain entity base package(s)
        return new SessionFactory(configuration, "me.neo4j.neo4jpoc.graph.entity");
    }

    @Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        ConfigurationSource properties = new ClasspathConfigurationSource("db.properties");
        return new org.neo4j.ogm.config.Configuration.Builder(properties).build();
    }


}

and finally here is my spring boot application class:

package me.neo4j.neo4jpoc;

import me.neo4j.neo4jpoc.graph.entity.MyEntity;
import me.neo4j.neo4jpoc.graph.repo.MyEntityRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class AccessingDataNeo4jApplication {

    private static final Logger LOG = LoggerFactory.getLogger(AccessingDataNeo4jApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(AccessingDataNeo4jApplication.class, args);
    }

    @Bean
    CommandLineRunner run(MyEntityRepository repository) {
        return args -> {

            MyEntity myEntity = repository.findQuery();
            System.out.println("myEntity = " + myEntity);
            LOG.debug("myEntity = {}", myEntity);
        };
    }
}

Also here is the cyphers for storing the data which I have stored inside my neo4j database through neo4j browser:

CREATE(l:PARENT {NAME:'ParentX'})
CREATE(w:MAIN {NAME:'Node1'})
CREATE(t:CHILD {NAME:'ChildY'})
CREATE (l)-[:CONSISTS_OF]->(w),(w)-[:CONSISTS_OF]->(t)
CREATE (l)<-[:BELONGS_TO]-(w),(w)<-[:BELONGS_TO]-(t)

Any input would be appreciated as I have no clue why it is not retrieving data.

Upvotes: 0

Views: 493

Answers (1)

cybersam
cybersam

Reputation: 66957

Your (single) entity class is named MyEntity and its @NodeEntity annotation does not specify the label name, so the associated node label defaults to MyEntity as well. Therefore, your Java code will only create and search for nodes with the MyEntity label.

On the other hand, your Cypher code is creating nodes with the labels PARENT, MAIN, and CHILD.

This is why your Java code never finds any nodes created by your Cypher code.

You will have change your Java and/or Cypher code to use the same node label(s). And you may also need to update the existing nodes in the DB to use the proper label(s).

Upvotes: 2

Related Questions