Сохранение репозитория() не работает

В настоящее время я играю с spring-data-neo4j и у меня действительно странное поведение с сохранением данных.

Я прочитал руководство по началу работы и просмотрел Хорошие отношения: руководство Spring Data Neo4j. Загрузка существующих узлов работает после избавления от мелких проблем и недостатков (например, использование spring-ogm 1.1.4 для избавления от зависимости neo4j-сервера).

Давайте посмотрим на мой код...

Это сущность:

package sdn.test.model;

import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;

@NodeEntity
public class TestUser {

    @GraphId
    private Long id;

    private String username;
    private String password;

    public TestUser() {
    }

    public TestUser(Long id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        TestUser testUser = (TestUser) o;

        if (getId() != null ? !getId().equals(testUser.getId()) : testUser.getId() != null) return false;
        if (getUsername() != null ? !getUsername().equals(testUser.getUsername()) : testUser.getUsername() != null)
            return false;
        return getPassword() != null ? getPassword().equals(testUser.getPassword()) : testUser.getPassword() == null;

    }

    @Override
    public int hashCode() {
        int result = getId() != null ? getId().hashCode() : 0;
        result = 31 * result + (getUsername() != null ? getUsername().hashCode() : 0);
        result = 31 * result + (getPassword() != null ? getPassword().hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "TestUser{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                "}";
    }
}

И это мой репозиторий:

package sdn.test.repository;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import sdn.test.model.TestUser;

@Repository
public interface UserRepository extends GraphRepository<TestUser> {

    @Query("MATCH (user:TestUser{username: {username}, password: {password}}) RETURN user")
    TestUser findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

}

Вот конфигурация neo4j:

package sdn.test.config;

import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.server.Neo4jServer;
import org.springframework.data.neo4j.server.RemoteServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@EnableNeo4jRepositories("sdn.test.repository")
@EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {

    @Bean
    @Override
    public Neo4jServer neo4jServer() {
        return new RemoteServer("http://localhost:7474", "neo4j", "test");
    }

    @Bean
    @Override
    public SessionFactory getSessionFactory() {
        return new SessionFactory("sdn.test.model");
    }

}

Все вместе живет в простом приложении Spring Boot, и я пытаюсь создать сущность в этом тестовом классе:

package sdn.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sdn.test.config.Neo4jConfig;
import sdn.test.model.TestUser;
import sdn.test.repository.UserRepository;

import java.util.Date;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
        Neo4jConfig.class})
public class SimpleNeo4jTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void createNewUser() {
        long timeOffset = (new Date()).getTime();
        String username = "test" + timeOffset;
        String password = "password@" + timeOffset;

        TestUser newUser = new TestUser(timeOffset, username, password);
        userRepository.save(newUser);

        // Try to load the user
        TestUser actualUser = userRepository.findByUsernameAndPassword(username, password);

        assertThat(actualUser, equalTo(newUser));
    }
}

И последнее, но не менее важное: вот мой 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.h0lg.test</groupId>
    <artifactId>simple-sdn4-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm</artifactId>
            <version>1.1.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
            <version>4.0.0.RELEASE</version>
        </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>

При вызове userRepository.save() ошибки не возникает, и проверка «удаленного» сервера подтверждает красный результат теста.

Явное указание имени метки с помощью @GraphEntity(label = "TestUser") не помогает. Явное использование транзакций также не помогло.

Любые идеи и подсказки приветствуются.


person incredibleholg    schedule 02.02.2016    source источник
comment
Пожалуйста, не могли бы вы включить ведение журнала отладки и опубликовать трассировку журнала запроса на сохранение, чтобы у нас было немного больше информации для работы.   -  person Vince    schedule 02.02.2016


Ответы (1)


Похоже, вы устанавливаете @GraphId вашего узла TestUser с помощью теста:

TestUser newUser = new TestUser(timeOffset, username, password);

public TestUser(Long id, String username, String password) {
    this.id = id;
    this.username = username;
    this.password = password;
}

Код приложения никогда не должен присваивать значение @GraphId. Не могли бы вы удалить это и посмотреть, поможет ли это?

person Luanne    schedule 02.02.2016
comment
Вот и все. Но это изменилось в одной из последних версий, не так ли? Я знаю, что пробовал это раньше, и я получил NPE из-за того, что id был нулевым... - person incredibleholg; 02.02.2016
comment
Ваш NPE мог исчезнуть из-за исправления ошибок, связанных с зависимостью OGM от объекта equals(). Но позиция, что поле @GraphId никогда не должно быть установлено, остается неизменной с самого первого релиза. - person Luanne; 02.02.2016
comment
Благодарю за разъяснение :) - person incredibleholg; 02.02.2016