title: No results querying a Neo4j database using Spring Data Neo4j repositories
body: <p>I have created a graph database as hierarchical tree as a result of converting a MySQL database in another Neo4j database. The transformation worked fine.</p>
  
  <p>On the top level exist a node labeled as Root, on the second level are the countries labeled as Country. Every country has cities that is the third level labeled as City. And down for every city there are a subset of addresses labeled as Address. The relationships should be,</p>
  
  <pre><code>(root)-[:IS_ROOT]-&gt;(country)-[:HAS_CITY]-&gt;(city)-[:HAS_ADDRESS]-&gt;(address)
  </code></pre>
  
  <p>Later, using Spring Data Neo4j repositories, I tried to query the database with no result.</p>
  
  <p>For the MySQL database I use JDBC, and for the Neo4j database I use Spring Data Neo4j as mentioned before.</p>
  
  <p>This is the controller I use to create the Neo4j database,</p>
  
  <pre><code>@Controller("importer")
  public class SakilaDbImportController {
  
  private static final Logger logger = LoggerFactory.getLogger(SakilaDbImportController.class);
  
  @Autowired
  @Lazy
  AddressNeoRepository addressRepo;
  
  @Autowired
  @Lazy
  CityNeoRepository cityRepo;
  
  @Autowired
  @Lazy
  CountryNeoRepository countryRepo;
  
  @Autowired
  @Lazy
  RootRepository rootRepo;
  
  @Autowired
  Neo4jTemplate template;
  
  @Autowired
  SakilaDbApiClient client;
  
  public SakilaDbImportController() {
  
  }
  
  @Transactional
  public RootNeo createGraphDb() {
      RootNeo root = doImportRoot();
      return root;
  }
  
  @Transactional
  public RootNeo importRoot() {
      return doImportRoot();
  }
  
  private RootNeo doImportRoot() {
      logger.debug("Importing root");
  
      RootNeo root = new RootNeo("1", "Root");
      root.addLabel("_Root");
      //root.addLabel("Root");
      System.out.println("root created " + root);
  
      List&lt;Country&gt; data = client.readAllCountries();
      if (data.isEmpty()) throw new RuntimeException("Data for Root not found.");
  
      Map&lt;CountryNeo, RoleIsRoot&gt; roles = relateCountriesToRoot(root, data);
      //template.save(root);
      Set&lt;CountryNeo&gt; set = roles.keySet();
      for(Iterator&lt;CountryNeo&gt; it = set.iterator(); it.hasNext();) {
          root.isRoot(it.next());
      }
      rootRepo.save(root);
  
      /*
      for(RoleIsRoot role: roles){
          template.save(role);
      }
      */
  
      return root;
  }
  
  private Map&lt;CountryNeo, RoleIsRoot&gt; relateCountriesToRoot(RootNeo root, List&lt;Country&gt; data) {
      Map&lt;CountryNeo, RoleIsRoot&gt; roles = new HashMap&lt;CountryNeo, RoleIsRoot&gt;();
      for (Country country : data) {
          if(country.getCountry().equalsIgnoreCase("Canada"))
              continue;
          CountryNeo countryNeo = doImportCountryNeo(country);
          RoleIsRoot role = root.isRoot(countryNeo, "IS_ROOT_OF");
          System.out.println("RoleIsRoot: " + role);
          roles.put(countryNeo, role);
      }
  
      return roles;
  }
  
  @Transactional
  public CountryNeo importCountryNeo(Country country) {
      return doImportCountryNeo(country);
  }
  
  private CountryNeo doImportCountryNeo(Country country) {
      logger.debug("Importing countryNeo");
  
      CountryNeo countryNeo = new CountryNeo(generateIndex(country.getCountryId()), country.getCountry());
      countryNeo.addLabel("_Country");
      //countryNeo.addLabel("Country");
      System.out.println("new country: " + countryNeo);
  
      List&lt;City&gt; data = client.readAllCitiesByCountry(country);
      if (data.isEmpty()) throw new RuntimeException("Data for Country not found.");
  
      Map&lt;CityNeo, RoleHasCity&gt; roles = relateCitiesToCountry(countryNeo, data);
      Set&lt;CityNeo&gt; set = roles.keySet();
      for(Iterator&lt;CityNeo&gt; it = set.iterator(); it.hasNext();) {
          countryNeo.hasCity(it.next());
      }
      countryRepo.save(countryNeo);
  
      /*
      template.save(countryNeo);
      for(RoleHasCity role: roles){
          template.save(role);
      }
      */
  
      return countryNeo;
  }
  
  private Map&lt;CityNeo, RoleHasCity&gt; relateCitiesToCountry(CountryNeo countryNeo, List&lt;City&gt; data) {
      Map&lt;CityNeo, RoleHasCity&gt; roles = new HashMap&lt;CityNeo, RoleHasCity&gt;();
      for (City city : data) {
          CityNeo cityNeo = doImportCityNeo(city);
          RoleHasCity role = countryNeo.hasCity(cityNeo, "IS_CITY_FROM");
          System.out.println("RoleHasCity: " + role);
          roles.put(cityNeo, role);
      }
  
      return roles;
  }
  
  @Transactional
  public CityNeo importCityNeo(City city) {
      return doImportCityNeo(city);
  }
  
  private CityNeo doImportCityNeo(City city) {
      logger.debug("Importing cityNeo");
  
      CityNeo cityNeo = new CityNeo(generateIndex(city.getCityId()), city.getCity());
      cityNeo.addLabel("_City");
      //cityNeo.addLabel("City");
      System.out.println("new city: " + cityNeo);
  
      List&lt;Address&gt; data = client.readAllAddressesByCity(city);
      if (data.isEmpty()) throw new RuntimeException("Data for City not found.");
  
      Map&lt;AddressNeo, RoleHasAddress&gt; roles = relateAddressesToCity(cityNeo, data);
      Set&lt;AddressNeo&gt; set = roles.keySet();
      for(Iterator&lt;AddressNeo&gt; it = set.iterator(); it.hasNext();) {
          cityNeo.hasAddress(it.next());
      }
      cityRepo.save(cityNeo);
  
      /*
      template.save(cityNeo);
      for(RoleHasAddress role: roles){
          template.save(role);
      }
      */
  
      return cityNeo;
  }
  
  private Map&lt;AddressNeo, RoleHasAddress&gt; relateAddressesToCity(CityNeo cityNeo, List&lt;Address&gt; data) {
      Map&lt;AddressNeo, RoleHasAddress&gt; roles = new HashMap&lt;AddressNeo, RoleHasAddress&gt;();
      for(Address address: data) {
          AddressNeo addressNeo = doImportAddressNeo(address);
          RoleHasAddress role = cityNeo.hasAddress(addressNeo, "IS_ADDRESS_IN");
          System.out.println("RoleHasAddress: " + role);
          roles.put(addressNeo, role);
      }
  
      return roles;
  }
  
  @Transactional
  public AddressNeo importAddressNeo(Address address) {
      return doImportAddressNeo(address);
  }
  
  private AddressNeo doImportAddressNeo(Address address) {
      logger.debug("Importing addressNeo");
  
      if (address == null) throw new RuntimeException("Address not found.");
  
      AddressNeo addressNeo = new AddressNeo(generateIndex(address.getAddressId()), address.getAddress());
      addressNeo.addLabel("_Address");
      //addressNeo.addLabel("Address");
      System.out.println("new address: " + addressNeo);
  
      addressNeo.setPostalCode(address.getPostalCode());
      addressRepo.save(addressNeo);
  
      /*
      template.save(addressNeo);
      */
  
      return addressNeo;
  }
  
  private String generateIndex(int index) {
      return String.valueOf(index);
  }
  }
  </code></pre>
  
  <p>And this is the service that, using the repositories, does the queries,</p>
  
  <pre><code>@Service
  public class SakilaDbQueries {
  
  @Autowired
  @Lazy
  AddressNeoRepository addressRepo;
  
  @Autowired
  @Lazy
  CityNeoRepository cityRepo;
  
  @Autowired
  @Lazy
  CountryNeoRepository countryRepo;
  
  @Autowired
  @Lazy
  RootRepository rootRepo;
  
  public SakilaDbQueries() {
  
  }
  
  public List&lt;String&gt; findAllCountryNames() {
      CountryNeoData names = countryRepo.findAllCountryNames();
      Collection&lt;String&gt; collection = names.getCountries();
  
      List&lt;String&gt; list = new ArrayList&lt;String&gt;();
      for(Iterator&lt;String&gt; it = collection.iterator(); it.hasNext(); ) {
          list.add(it.next());
      }
  
      return list;
  }
  
  public List&lt;CountryNeo&gt; findAllCountries() {
      Result&lt;CountryNeo&gt; result = countryRepo.findAll();
  
      List&lt;CountryNeo&gt; list = new ArrayList&lt;CountryNeo&gt;();
      for(Iterator&lt;CountryNeo&gt; it = result.iterator(); it.hasNext(); ) {
          list.add(it.next());
      }
  
      return list;
  }
  }
  </code></pre>
  
  <p>And as an example,</p>
  
  <p>Here is the NodeEntity Place as generic one,</p>
  
  <pre><code>@NodeEntity
  public class Place {
  
  @GraphId Long nodeId;
  
  @Indexed(unique=true)
  String id;
  
  @Indexed(indexType=IndexType.FULLTEXT, indexName = "place")
  String name;
  
  @Labels 
  private Collection&lt;String&gt; labels = Collections.emptySet(); 
  
  
  protected Place(String id, String name) {
      this.id = id;
      this.name = name;
  }
  
  protected Place() {
  }
  
  public String getId() {
      return id;
  }
  
  public String getName() {
      return name;
  }
  
  public void setName(String name) {
      this.name = name;
  }
  
  public void addLabel(String label) {
      HashSet&lt;String&gt; newLabels = new HashSet&lt;&gt;(this.labels);
      if (newLabels.add(label)) this.labels = newLabels;
  }
  
  public void removeLabel(String label) {
      HashSet&lt;String&gt; newLabels = new HashSet&lt;&gt;(this.labels);
      if (newLabels.remove(label)) this.labels = newLabels;
  }
  
  @Override
  public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
  
      Place place = (Place) o;
      if (nodeId == null) return super.equals(o);
      return nodeId.equals(place.nodeId);
  
  }
  
  @Override
  public int hashCode() {
      return nodeId != null ? nodeId.hashCode() : super.hashCode();
  }
  
  @Override
  public String toString() {
      return String.format("%s [%s]", name, id);
  }
  
  }
  </code></pre>
  
  <p>and CountryNeo that extends Place,</p>
  
  <pre><code>@NodeEntity
  public class CountryNeo extends Place {
  
  @RelatedTo(type = "HAS_CITY", direction = Direction.OUTGOING)
  Set&lt;CityNeo&gt; cities;
  
  @Fetch @RelatedToVia(type = "IS_ROOT", direction = Direction.INCOMING)
  Iterable&lt;RoleIsRoot&gt; roles;
  
  public CountryNeo() {
  }
  
  public CountryNeo(String id, String name) {
      super(id, name);
  }
  
  public Set&lt;CityNeo&gt; getCities() {
      return cities;
  }
  
  public void hasCity(CityNeo city) {
      if(cities == null)
          cities = new HashSet&lt;CityNeo&gt;();
      cities.add(city);
  }
  
  public RoleHasCity hasCity(CityNeo city, String roleName) {
      return new RoleHasCity(this, city, roleName);
  }
  
  public Collection&lt;RoleIsRoot&gt; getRoles() {
      Iterable&lt;RoleIsRoot&gt; allRoles = roles;
      return allRoles == null ? Collections.&lt;RoleIsRoot&gt;emptyList() : IteratorUtil.asCollection(allRoles);
  }
  }
  </code></pre>
  
  <p>The used roles,</p>
  
  <pre><code>@RelationshipEntity(type = "HAS_CITY")
  public class RoleHasCity {
  @GraphId Long id;
  
  @StartNode CountryNeo country;
  @EndNode CityNeo city;
  
  String name;
  
  public RoleHasCity() {
  
  }
  
  public RoleHasCity(CountryNeo country, CityNeo city, String roleName) {
      this.country = country;
      this.city = city;
      this.name = roleName;
  }
  
  public String getName() {
      return name;
  }
  
  public void setName(String name) {
      this.name = name;
  }
  
  public CountryNeo getCountry() {
      return country;
  }
  
  public void setCountry(CountryNeo country) {
      this.country = country;
  }
  
  public CityNeo getCity() {
      return city;
  }
  
  public void setCity(CityNeo city) {
      this.city = city;
  }
  
  @Override
  public String toString() {
      return String.format("%s %s %s", city, name, country);
  }
  }
  </code></pre>
  
  <p>And the repository,</p>
  
  <pre><code>public interface CountryNeoRepository extends GraphRepository&lt;CountryNeo&gt; {
  
  @Query("MATCH (n:CountryNeo) RETURN COLLECT(n.name) AS countries")
  CountryNeoData findAllCountryNames();
  
  @QueryResult
  public class CountryNeoData {
      Collection&lt;String&gt; countries = Collections.emptyList();
  
      public Collection&lt;String&gt; getCountries() {
          return countries;
      }
  }
  }
  </code></pre>
  
  <p>And here is the main bean,</p>
  
  <pre><code>public class SakilaImporter {
  
  private GraphDatabaseService graphDatabase;
  private SakilaDbImportController importer;
  private SakilaDbQueries queries;
  
  public SakilaImporter(GraphDatabaseService graphDatabase,
          SakilaDbImportController importer,
          SakilaDbQueries queries) {
      this.graphDatabase = graphDatabase;
      this.importer = importer;
      this.queries = queries;
  }
  
  public static void main(String[] args) {
      // TODO Auto-generated method stub
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
  
      GraphDatabaseService graphDatabase = ctx.getBean("graphDatabaseService", GraphDatabaseService.class);
      SakilaDbImportController importer = ctx.getBean("importer", SakilaDbImportController.class);
      SakilaDbQueries queries = ctx.getBean("queries", SakilaDbQueries.class);
  
      SakilaImporter sakilaImporter = new SakilaImporter(graphDatabase, importer, queries);
  
      Transaction tx = graphDatabase.beginTx();
      try {
          sakilaImporter.createDatabase();
          sakilaImporter.queryDatabase();
          tx.success();
      } finally {
          tx.close();
      }
      ctx.close();
  }
  
  public void createDatabase() {
      System.out.println("Importing data...");
      final long start = System.currentTimeMillis();
      RootNeo root = importer.createGraphDb();
      if(root != null) {
          final long time = System.currentTimeMillis() - start;
          System.out.println("Import places took " + time + " ms.");
      } else {
          System.out.println("root: " + root);
      }    
  }
  
  public void queryDatabase() {
      System.out.println();System.out.println();
      System.out.println("List of countries.-");
      List&lt;CountryNeo&gt; countries = queries.findAllCountries();
      for(CountryNeo country: countries) {
          System.out.println(country);
      }
      System.out.println();System.out.println();
      System.out.println("List of country names.-");
      List&lt;String&gt; names = queries.findAllCountryNames();
      for(String name: names) {
          System.out.println(name);
      }
  }
  }
  </code></pre>
  
  <p>The result of both queries is an empty list</p>
  
  <ul>
  <li>spring 2.5.6</li>
  <li>spring framework 4.0.0.RELEASE</li>
  <li>neo4j 2.1.8</li>
  <li>spring data neo4j 3.1.2.RELEASE</li>
  </ul>