6

I've been playing with Neo4j 2.0 RC1 for a couple of weeks. I'm writing a Spring Security implementation using Neo4j as the database. When I load a user, the response I get from Neo4j looks like this:

{
    "columns" : [ "username", "password", "accountNonExpired","accountNonLocked", "credentialsNonExpired", "enabled" ],
    "data" : [ [ "admin", "admin", true, false, true, false ]
}

Originally the only fields returned where username and password (both strings) and I was able to do this:

class Result
{
    private List<String> columns = new ArrayList<String>();

    private List<ArrayList<String>> data = new ArrayList<ArrayList<String>>();

};

ClientRespose resp = webResource.path(path).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, body );
String s = response.getEntity(String.class);
Result r = new Gson().fromJson(s, Result.class);

Of course when I added the other fields (booleans) I needed to change Result to look like this:

class Result
{
    private List<String> columns = new ArrayList<String>();

    private List<ArrayList<Object>> data = new ArrayList<ArrayList<Object>>();

};

My code still worked, but when I tried to cast any of the data items to String or Boolean I got a 'failed to cast Object to...' exception. This is of course because there is no type information, so GSon is creating Object instances to put everything it.

So I'm guessing there must be a better way to process the JSON that comes back from Neo4j?

Can I somehow skip the JSON conversion stage and get the Jersey HTTP client to populate my User objects directly?

1 Answer 1

2

The problem is that the data is not returned as map.

I usually do this:

  1. get the result as Map
  2. get the columns list
  3. get the data nested list
  4. using an for loop over data to get each row
  5. using a for loop over columns and it's index to access the data in the row

You can also add a factory method to your user Object that gets one of these results rows and constructs your User object.

e.g.

class User {
   public static User from(List<Object> row) {
      User u=new User((String)row.get(0),(String)row.get(1));
      u.setAccountNonExpired((Boolean)row.get(2));
      u.setAccountNonLocked((Boolean)row.get(3));
      u.setCredentialsNonExpired((Boolean)row.get(4));
      u.setEnabled((Boolean)row.get(5));
      return u;
   }
}

Something you can try with Neo4j 2.0 is to use the transactional endpoint and return the node object (which will return just the node-properties as a map), which you then can map directly with Gson or Jackson to an object (the row).

match (u:User {username:{username}})
return u

otherwise you can also use the literal map syntax in Neo4j 2.0

match (u:User {username:{username}})
return {username : u.username, password: u.password, ....} as user
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.