Hot questions for Using Neo4j in json

Question:

I am building a Neo4J plugin using jersey-json to parse my POJO's to and from json. The problem is that my REST-services return numbers as strings.

If a POJO looks like this:

@XmlRootElement
public class Item {
    private Integer value = 5;
    private int primitiveValue = 6;

    public Item() {}

    public Integer getValue() {
        return value;
    }

    public int getPrimitiveValue() {
        return primitiveValue;
    }
}

I get a JSON-object looking like this:

{
    value: "5",
    primitiveValue: "6"
}

But I would expect it to be like this:

{
    value: 5,
    primitiveValue: 6
}

My resource looks like this:

@GET
@Path("/item")
@Produces(MediaType.APPLICATION_JSON)
public Response getItem() {
    return Response.ok(new Item()).build();
}

My pom looks like this:

<?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>my.project.id</groupId>
    <artifactId>neo4j-extension</artifactId>
    <version>1.0</version>

    <properties>
        <neo4j.version>2.2.0</neo4j.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j</artifactId>
            <version>${neo4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>server-api</artifactId>
            <version>${neo4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.neo4j.app</groupId>
            <artifactId>neo4j-server</artifactId>
            <version>${neo4j.version}</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.18.1</version>
        </dependency>

    </dependencies>

</project>

Do you know how I could solve this problem? Why is the default behavior to parse numeric fields as strings?

Solution

After suggestion from Stefan Armbruster I added the following dependency to my pom, and all dependent jars to my /plugins folder.

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.6.2</version>
</dependency>

And removed @XmlRootElement annotation from my POJO.

The difference from before is that I get all null-values in my response. With the @XmlRootElement annotation null-values are removed from the response, but I do not think this will be a problem.


Answer:

Try to change your JAX-RS method to:

@GET
@Path("/item")
@Produces(MediaType.APPLICATION_JSON)
public Item getItem() {
    return new Item();
}

If you get an error, amend http://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson http://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/2.6.2 to your dependencies (and make sure that this jar is deployed to the plugins folder as well).

Question:

Hi Graphista and other Java gurus,

I have changed my code according to answer given and after inspecting the example provided by neo4j, but still to no avail. So please, could anyone help me with this???

I have a java program which connects to a Neo4J REST API endpoint via jersey client (version 2.11 from org.glassfish.jersey.core).

this is what I do:

        logger.trace("sending cypher {} to endpoint {}", cypherString, nodePointUrl);
        WebResource resource2 = Client.create().resource( nodePointUrl );

        ClientResponse response2 = resource2
                .accept( "application/json" )
                .type( "application/json" )
                .entity( cypherString )
                .post( ClientResponse.class );

        logger.debug("POST to {} returned status code {}, returned data: {}",
                nodePointUrl, response2.getStatus(),
                response2.getEntity(String.class));

        HttpStatusCodes httpStatusCodes = HttpStatusCodes.getHttpStatusCode(response2.getStatus());

The json in the cypherstring I send to the rest api looks like this:

{"CREATE": [{"POST": {"id":"532552232906940416","text":"Warburg Research...","subject":"Warburg Research ...","teaser":"Warburg Research...","lang":"de"}}]}

The error message I receive on this is:

 java.lang.String cannot be cast to java.util.Map

As you can see, my code is rather simple. I have taken it straight from neo4j website (http://neo4j.com/docs/stable/server-java-rest-client-example.html) - but it always bails out (see log below).

Please see the error log and give me a hint on what I did wrong.

Thanks in advance,

Christian

"message" : "java.lang.String cannot be cast to java.util.Map",
"exception" : "BadInputException",
"fullname" : "org.neo4j.server.rest.repr.BadInputException",
"stacktrace" : [ "org.neo4j.server.rest.repr.formats.JsonFormat.readMap(JsonFormat.java:92)", "org.neo4j.server.rest.web.RestfulGraphDatabase.createNode(RestfulGraphDatabase.java:238)", "java.lang.reflect.Method.invoke(Method.java:606)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "java.lang.Thread.run(Thread.java:745)" ],
"cause" : {
   "message" : "java.lang.String cannot be cast to java.util.Map",
   "exception" : "ClassCastException",
   "stacktrace" : [ "org.neo4j.server.rest.domain.JsonHelper.jsonToMap(JsonHelper.java:53)", "org.neo4j.server.rest.repr.formats.JsonFormat.readMap(JsonFormat.java:88)", "org.neo4j.server.rest.web.RestfulGraphDatabase.createNode(RestfulGraphDatabase.java:238)", "java.lang.reflect.Method.invoke(Method.java:606)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "java.lang.Thread.run(Thread.java:745)" ],
  "fullname" : "java.lang.ClassCastException"
  }
}

Answer:

If your cypherString looks like that, then it's probably wrong. It's trying to parse JSON, and you're not providing it JSON. As you can see from the example, their payload is:

String payload = "{\"statements\" : [ {\"statement\" : \"" +query + "\"} ]}";

You should do the same thing, but replace query with your variable, cypherString. As a result, you would have:

String payload = "{\"statements\" : [ {\"statement\" : \"" + cypherString + "\"} ]}";
ClientResponse response = resource
        .accept( MediaType.APPLICATION_JSON )
        .type( MediaType.APPLICATION_JSON )
        .entity( payload )
        .post( ClientResponse.class );

Question:

I am using the Advanced Rest Client tool to test a server side java class that processes data sent in as a json object and am encountering an error that has me stumped. After much Google searches and trial and error attempts, I now turn to SO.

Some details on the problem.

-> Below is the test data being passed into the java class. The data is in a valid format - verified the data via a validation tool.

[{ "Id":1,"Question":"What is the capital of Texas", "QuestionType":"SingleChoice",
"Options":[{ "Answer":1,"City":"Austin"}, { "Answer":2, "City":"Houston" }, { 
"Answer":3, "City":"El Paso" }] }] 

-> I am using the Post option on the Advanced Rest Client tool.

-> application/json is the type used for this post.

-> the server side class is to post information to a Neo4J database and thus the Neo4J server is being used. The server is up and running and I am able to send other transactions to other classes with no issues.

-> when I send the transaction using the above data-set, I encounter the below error...

message: "java.util.ArrayList cannot be cast to java.util.Map"
exception: "BadInputException"
fullname: "org.neo4j.server.rest.repr.BadInputException"
stacktrace: [6]
  0:  "org.neo4j.server.rest.repr.formats.JsonFormat.readMap(JsonFormat.java:92)"
  1:  "org.neo4j.server.rest.repr.RepresentationFormat.
        readParameterList(RepresentationFormat.java:97)"
  2:  "org.neo4j.server.rest.web.ExtensionService.
       invokeGraphDatabaseExtension(ExtensionService.java:134)"
  3:  "java.lang.reflect.Method.invoke(Unknown Source)"
  4:  "org.neo4j.server.rest.transactional.
      TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)"
  5:  "java.lang.Thread.run(Unknown Source)" -
  cause: {
    message: "java.util.ArrayList cannot be cast to java.util.Map"
    exception: "ClassCastException"
    stacktrace: [7]
  0:  "org.neo4j.server.rest.domain.JsonHelper.jsonToMap(JsonHelper.java:53)"
  1:  "org.neo4j.server.rest.repr.formats.JsonFormat.readMap(JsonFormat.java:88)"
  2:  "org.neo4j.server.rest.repr.RepresentationFormat.
        readParameterList(RepresentationFormat.java:97)"
  3:  "org.neo4j.server.rest.web.ExtensionService.
         invokeGraphDatabaseExtension(ExtensionService.java:134)"
  4:  "java.lang.reflect.Method.invoke(Unknown Source)"
  5:  "org.neo4j.server.rest.transactional.
      TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)"
   6:  "java.lang.Thread.run(Unknown Source)"
      -
      fullname: "java.lang.ClassCastException" 
  }

With the above in mind, I am leaning towards to error being encountered at the Advanced Rest Client tool level and not by the java class. The reason for that is when a name of a non-existent class is used on the call, I get the same error.

Nor sure what other information can be provided to help resolve this. Please let me know if you need additional details.

Thanks in advance.


Answer:

Got it! Removing the outer brackets ([ ]) did the trick. Doing so had the data encased by the {} brackets state that a JSON object is being sent (I believe).

Question:

I want to load my Json file into neo4j server using Apoc procedure, for that I used following query...

call apoc.load.json("file:///training.json") yield value Return value    

but it is showing me the error

"Failed to invoke procedure apoc.load.json: Caused by: java.lang.RuntimeException: Can't read url file:///training.json as json: \training.json (The system cannot find the file specified)".

Expected behaviour is Specified json file is to be loaded in to neo4j server.

problem is: It is not at all recognizing the file That is specified in URL.

please help me out to resolve this error


Answer:

call apoc.load.json("file:///training.json") yield value Return value 

for the above query the URL is specified as "file:///training.json". Instaed of this Specify full path name in URL.

for eg: I put my json file named "training.json" in following specified path

C:\Users\TEMP.DESKTOP9FCLQ6J.002\Documents\Neo4j\default.graphdb\import\training.json

so in query specify the above full path name. Instead of C:// specify the protocol name file:///

The correct answer is:

call apoc.load.json("file:///Users\\TEMP.DESKTOP-9FCLQ6J.002\\Documents\\Neo4j\\default.graphdb\\import\\test.json") yield value 
Return value.

Thanks.

Question:

Current Situation: I have two files, one in JSON format and the other in CSV format. I would like to parse them in Java and store the results in a Neo4j DB for later use.

What I have till now: I have used Jackson Library to parse the JSON file and for the CSV file I have done as follows:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CSVReader {

    public static void main(String[] args) {

        String csvFile = "path/to/file/data.csv";
        String line = "";
        String cvsSplitBy = ",";

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {

            while ((line = br.readLine()) != null) {


                String[] dataPoints = line.split(cvsSplitBy);

                System.out.println("Data [point1= " + dataPoints[4] + " , point3=" + dataPoints[3] + "]");

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Problem: I can display the results fine but I would like to store them in a Neo4j Database. I don't know how to proceed with that. Can anyone help or point me to the right direction? I just started with Neo4j so some extra clarification regarding the code/steps would be really helpful.

EDIT: For example, with MySQL I would do something like this to insert values into a table.

String query = " insert into users (first_name, last_name, dob, email_id)"
        + " values (?, ?, ?, ?)";

      // create the mysql insert preparedstatement
      PreparedStatement preparedStmt = conn.prepareStatement(query);

      // code to set values

      // execute the preparedstatement
      preparedStmt.execute();

What would be the equivalent in Neo4J?

Note: Downvoting a question without explaining what is wrong with it doesn't really achieve anything. There's criticism and then there's constructive criticism. Thanks!


Answer:

Are you trying to find out how to interact with a database in Java? The native way is via JDBC, but there are other options. The Neo4J JDBC driver documentation (https://neo4j.com/blog/neo4j-jdbc-driver-3-3-1-release/) has some good pointers on how to proceed. As to parsing, the CSV parsing code you have here looks good and the Jackson library is a fine option for parsing JSON. Can you elaborate on what you're looking for?

Question:

Current Situation: I have two files, one in JSON format and the other in CSV format. I would like to parse them in Java and store the results in a Neo4j DB for later use.

What I have till now: I have used Jackson Library to parse the JSON file and for the CSV file I have done as follows:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CSVReader {

    public static void main(String[] args) {

        String csvFile = "path/to/file/data.csv";
        String line = "";
        String cvsSplitBy = ",";

        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {

            while ((line = br.readLine()) != null) {


                String[] dataPoints = line.split(cvsSplitBy);

                System.out.println("Data [point1= " + dataPoints[4] + " , point3=" + dataPoints[3] + "]");

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Problem: I can display the results fine but I would like to store them in a Neo4j Database. I don't know how to proceed with that. Can anyone help or point me to the right direction? I just started with Neo4j so some extra clarification regarding the code/steps would be really helpful.

EDIT: For example, with MySQL I would do something like this to insert values into a table.

String query = " insert into users (first_name, last_name, dob, email_id)"
        + " values (?, ?, ?, ?)";

      // create the mysql insert preparedstatement
      PreparedStatement preparedStmt = conn.prepareStatement(query);

      // code to set values

      // execute the preparedstatement
      preparedStmt.execute();

What would be the equivalent in Neo4J?

Note: Downvoting a question without explaining what is wrong with it doesn't really achieve anything. There's criticism and then there's constructive criticism. Thanks!


Answer:

Are you trying to find out how to interact with a database in Java? The native way is via JDBC, but there are other options. The Neo4J JDBC driver documentation (https://neo4j.com/blog/neo4j-jdbc-driver-3-3-1-release/) has some good pointers on how to proceed. As to parsing, the CSV parsing code you have here looks good and the Jackson library is a fine option for parsing JSON. Can you elaborate on what you're looking for?