Search code examples
javaneo4jneo4j-ogm

Find node by its property name using neo4j OGM


I have my SkillCluster class as follows

public class SkillCluster {
    @Id @GeneratedValue
    private Long id;
    private String Name;
    private String CleanedText;

    @Relationship(type = "BelongsTo", direction = Relationship.INCOMING)
    private Set<Skill> contains = new HashSet<>();
}

Its corresponding DAO class

import org.neo4j.ogm.session.Session;
import com.models.GenericDAO;

public class SkillClusterDAO extends GenericDAO<SkillCluster>{
    public SkillClusterDAO(Session session) {
        super(session);
    }

    protected Class<SkillCluster> getEntityType() {
        return SkillCluster.class;
    }   
}

and my GenericDAO class as

public abstract class GenericDAO<T> {
    private static final int DEPTH_LIST = 0;
    private static final int DEPTH_ENTITY = 1;  
    private Session session;

    public long filterCount(Iterable<Filter> filters){
        return session.count(getEntityType(), filters);
    }

    public T find(Long id) {
        return session.load(getEntityType(), id, DEPTH_ENTITY);
    }

    public T find(String name) {
        return session.load(getEntityType(), name, DEPTH_ENTITY);
    }

    public void delete(Long id) {
        session.delete(session.load(getEntityType(), id));
    }

    public void createOrUpdate(T entity) {
        session.save(entity, DEPTH_ENTITY);
        //return find(entity.id);
    }

    protected abstract Class<T> getEntityType();

    public GenericDAO(Session session) {
        this.session = session;
    }
}

I wanted to get the cluster node by matching the Node property Name by doing this

skillSessionFactory = new SessionFactory(skillConfiguration, "com.skill.models");
skillSession = skillSessionFactory.openSession();

skillClusterDAO = new SkillClusterDAO(skillSession);
SkillCluster clusterNode = skillClusterDAO.find(cluster_name);

I am getting the follwing error -

java.lang.IllegalArgumentException: Supplied id must be of type Long (native graph id) when supplied class does not have primary id - com.models.SkillCluster

Solution

  • You have this error because the name property isn't a Long.

    Even if your name property would have been a Long too, it wouldn't works because it would have been fetched a wrong node.

    session.load(...) works for internal node Id, or with property marked as @Id or primary index @Index(primary = true).

    If you need to find node by its property otherwise than the primary key, you could use session.loadAll(...) with filter.

    public abstract class GenericDAO<T> {
    
      ...
    
      import java.util.Collection;
      import java.util.Optional;
      import org.neo4j.graphdb.GraphDatabaseService;
      import org.neo4j.ogm.cypher.Filter;
      ...
    
      public T find(Long id) {
        return session.load(getEntityType(), id, DEPTH_ENTITY);
      }
    
      public T find(String name) {
        final String propertyName = "name";
        Filter filter = new Filter(propertyName, name);
    
        Collection<T> results = session.loadAll(getEntityType(), filter, DEPTH_ENTITY);
    
        if( results.size() > 1)
          throw new CustomRuntimesException("Too results found");
    
        Optional<T> entity = results.stream().findFirst();
    
        return entity.isPresent() ? entity.get() : null;
     }
    
     ...
    
    }