1
votes

I have started to use SDN 3.0.0 M1 with Neo4j 2.0 (via rest interface) and I want use an existing graph.db with existing datas.

I have no problem to find node created through SDN via hrRepository.save(myObject); but I can't fetch any existing node (not created through SDN), via hrRepository.findAll(); or any other method, despite I have manually added a property __type__ in this existing nodes.

I use a very simple repository to test that :

@Component
public interface HrRepository extends GraphRepository<Hr> {

    Hr findByName(String name);

    @Query("match (hr:hr) return hr")
    EndResult <Hr> GetAllHrByLabels();
}

And the named query GetAllHrByLabels work perfectly.

Is an existing way to use standard methods (findAll() , findByName()) on existing datas without redefine Cypher query ?

2

2 Answers

2
votes

I recently ran into the same problem when upgrading from SDN 2.x to 3.0. I was able to get it working by first following the steps in this article: http://maxdemarzi.com/2013/06/26/neo4j-2-0-is-coming/ to create and enable Neo4j Labels on the existing data.

From there, though, I had to get things working for SDN 3. As you encountered, to do this, you need to set the metadata correctly. Here's how to do that:

Consider a @NodeEntity called Person, that inherits from AbstractNodeEntity (imports and extraneous code removed for brevity):

AbstractNodeEntity:

@NodeEntity
public abstract class AbstractNodeEntity {
  @GraphId private Long id;
}

Person:

@NodeEntity
@TypeAlias("Person")    // <== This line added for SDN 3.0
public class Person extends AbstractNodeEntity {
  public String name;
}

As you know, in SDN 2.x, a __type__ property is created automatically that stores the class name used by SDN to instantiate the node entity when it's read from Neo4j. This is still true, although in SDN 3.0 it's now specified using the @TypeAlias annotation, as seen in the example above. SDN 3.0 also adds new metadata in the form of Neo4j Labels representing the class hierarchy, where the node's class is prepended with an underscore (_).

For existing data, you can add these labels In Cypher (I just used the new web-based Browser utilty in Neo4j 2.0.1) like this:

MATCH (n {__type__:'Person'}) SET n:`_Person`:`AbstractNodeEntity`;

Just wash/rinse/repeat for other @NodeEntity types you have.

There is also a Neo4j Label that gets created called SDN_LABEL_STRATEGY but it isn't applied to any nodes, at least in my data. SDN 3 must have created it automatically, as I didn't do so manually.

Hope this helps...

-Chris

0
votes

Using SDN over REST is probably not the best idea performance-wise. Just that you know.

Data not created with SDN won't have the necessary meta information.

You will have to iterate over the nodes manually and use

template.postEntityCreation(Node,Class);

on each of them to add the type information. Where class is your SDN annotated entity class.

something like:

for (Node n : template.query("match(n) where n.type = 'Hr' return n").to(Node.class)) 
  template.postEntityCreation(n,Hr.class);