Search code examples
neo4jjava-8spring-dataspring-data-neo4j-4

Neo4j spring data Data polution


Neo4j Node

 {
    "id": 109433,
    "name": "test",
    "value": [
      "c"
    ]
  }

Having the node above I execute this post to modify my object so the value contains "a","b" instead of "c":

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d ' {
    "id": 109433,
    "name": "test",
    "value": [
      "a","b"
    ]
  }' 'http://localhost:8080/configs'

Then I execute a get to get all nodes

curl -X GET --header 'Accept: application/json' 'http://localhost:8080/configs'

For some weird reason it will return

{
    "id": 109433,
    "name": "test",
    "value": [
      "a",
      "b",
      "c"
    ]
  }

If I go to neo4j outside my web application and query it I will get

Node after post

 {
    "id": 109433,
    "name": "test",
    "value": [
      "a","b"
    ]
  }

So just to be sure I have some sort of data pollution like a cache running somewhere I stop the server and turn it on again, then I do the get again

curl -X GET --header 'Accept: application/json' 'http://localhost:8080/configs'

returns:

{
    "id": 109433,
    "name": "test",
    "value": [
      "a",
      "b",
    ]
  }

So now "c" is nowhere to be seen. Here is the code I'm using

api

package io.swagger.api;
import io.swagger.annotations.*;
import io.swagger.model.Config;
import io.swagger.service.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

@RestController
@RequestMapping(value = "/configs", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/configs", description = "the configs API")
public class ConfigsApi {

  @Autowired
  private ConfigService configService;


  @ApiOperation(value = "", notes = "Gets `Config` objects. ", response = Config.class, responseContainer = "List")
  @ApiResponses(value = {
          @ApiResponse(code = 200, message = "Successful response", response = Config.class) })
  @RequestMapping(value = "", produces = { "application/json" }, method = RequestMethod.GET)
  public ResponseEntity<List<Config>> getAllConfigs() throws NotFoundException {
    return new ResponseEntity<List<Config>>(configService.getAll(),HttpStatus.OK);
  }
  @ApiOperation(value = "", notes = "Creates/updates `Config` object. ", response = Void.class)
  @ApiResponses(value = { 
    @ApiResponse(code = 200, message = "successful operation", response = Void.class),
    @ApiResponse(code = 400, message = "Invalid Config", response = Void.class) })
  @RequestMapping(value = "", produces = { "application/json" }, method = RequestMethod.POST)
  public ResponseEntity<Void> createConfigByKey( @ApiParam(value = "Updated user object" ,required=true ) @RequestBody Config body ) throws NotFoundException {
    configService.merge(body);
    return new ResponseEntity<Void>(HttpStatus.OK);
  }
}

Service

package io.swagger.service;

import com.google.common.collect.Lists;
import io.swagger.model.Config;
import io.swagger.repository.ConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class ConfigService {

    @Autowired
    private ConfigRepository configRepository;

    public List<Config> getAll() {return Lists.newArrayList(configRepository.findAll());}
    public void merge(Config c){configRepository.save(c);}
}

Repository

package io.swagger.repository;

import io.swagger.model.Config;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;

public interface ConfigRepository extends GraphRepository<Config> {
}

Neo4j Configuration

package io.swagger.configuration;

import org.neo4j.ogm.session.SessionFactory;
import org.springframework.beans.factory.annotation.Value;
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;

@Configuration
@EnableNeo4jRepositories("io.swagger.*")
public class InventoryApiNeo4jConfiguration extends Neo4jConfiguration {
    @Value("${neo4j.ogm.driver}")
    private String driver;

    @Value("${neo4j.ogm.URI}")
    private String uri;

    @Value("${neo4j.ogm.connection.pool.size}")
    private int connectionPoolSize;

    @Value("${neo4j.ogm.encryption.level}")
    private String encryptionLevel;

    @Bean
    public org.neo4j.ogm.config.Configuration getConfiguration() {
        org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration();
        configuration.driverConfiguration()
                .setDriverClassName(driver)
                .setURI(uri)
                .setConnectionPoolSize(connectionPoolSize)
                .setEncryptionLevel(encryptionLevel);
        return configuration;
    }

    @Override
    @Bean
    public SessionFactory getSessionFactory() {
        return new SessionFactory(getConfiguration(), "io.swagger");
    }
}

Pom

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-springboot-server</artifactId>
    <packaging>jar</packaging>
    <name>swagger-springboot-server</name>
    <version>1.0.0</version>
    <properties>
        <springfox-version>2.4.0</springfox-version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RC1</version>
    </parent>
    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        <!--SpringFox dependencies -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox-version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox-version}</version>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
            <scope>provided</scope>
        </dependency>
        <!-- Neo4J -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
            <version>4.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-bolt-driver</artifactId>
            <version>2.0.3</version>
        </dependency>
    </dependencies><repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
</project>

Solution

  • Updated Spring boot from 1.4.0.RC1 to 1.4.0.RELEASE and now it does not occur.