Search code examples
neo4jneo4j-ogm

Struggling with retrieving an entity from Neo4j using a primary index


I have the following simple inheritance hierarchy

    abstract class Entity {

        @GraphId
        Long id;

        public Long getId() {
            return id;
        }
    }


    @NodeEntity
    public class Asset extends Entity {

        String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Index(unique=true, primary=true)
        String primaryKey;

        public String getPrimaryKey() {
            return primaryKey;
        }

        public void setPrimaryKey(String primaryKey) {
            this.primaryKey = primaryKey;
        }
   }

@NodeEntity
public class Equity extends Asset {

    @Override
    public String toString() {
        return "Equity [name=" + name + ", primaryKey=" + primaryKey + "]";
    }

}

And my repository is implemented as:

public class AssetServiceImpl extends GenericService<Asset> implements AssetService {

    @Override
    public Asset findPK(String primaryKey)
    {
        return session.load(getEntityType(), primaryKey, 0);
    }

    @Override
     public Asset create(Asset asset) {

            Asset foundAsset = findPK(asset.getPrimaryKey()); 
            if (foundAsset == null)
            {
                session.save(asset, 0);
                return findPK(asset.getPrimaryKey());
            }
            else
            {
                return foundAsset;
            }
    }

    @Override
    public Class<Asset> getEntityType() {
        return Asset.class;
    }
}

I'm Testing with the simple App:

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );        

        AssetService assetService = new AssetServiceImpl();

        Equity equity1 = new Equity();
        equity1.setName("British Airways");
        equity1.setPrimaryKey("PK1");

        assetService.create(equity1);

        System.out.println(assetService.findPK("PK1"));       
        return;     
    }
}

When I run the App the Equity gets created as expected in the database with all properties and tags to represent inheritance as one would expect. The problem is that the method findPK will only return null. So starting with a clean db I

  • Look for it and dont find it OK
  • Create it OK
  • Look for it again and don't find it PROBLEM

The Logging shows the creation of the constraints, the creation of the equity and the attempts to find it. On the face of it all looks good but nothing is being found! I'd be very grateful for any tips on this I'm sure I'm missing something silly.

Hello World!
[main] INFO org.neo4j.ogm.metadata.ClassFileProcessor - Starting Post-processing phase
[main] INFO org.neo4j.ogm.metadata.ClassFileProcessor - Building annotation class map
[main] INFO org.neo4j.ogm.metadata.ClassFileProcessor - Building interface class map for 14 classes
[main] INFO org.neo4j.ogm.metadata.ClassFileProcessor - Post-processing complete
[main] INFO org.neo4j.ogm.metadata.ClassFileProcessor - 14 classes loaded in 80728985 nanoseconds
[main] INFO org.neo4j.ogm.service.DriverService - Using: [org.neo4j.ogm.drivers.bolt.driver.BoltDriver]
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: CALL db.constraints() with params {}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: CALL db.indexes() with params {}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: DROP CONSTRAINT ON ( asset:Asset ) ASSERT asset.primaryKey IS UNIQUE with params {}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: CREATE CONSTRAINT ON ( asset:Asset ) ASSERT asset.primaryKey IS UNIQUE with params {}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: MATCH (n) WHERE n.primaryKey = { id } RETURN n with params {id=PK1}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: UNWIND {rows} as row CREATE (n:`Equity`:`Asset`) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type with params {rows=[{nodeRef=-1647809929, type=node, props={name=British Airways, primaryKey=PK1}}]}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: MATCH (n) WHERE n.primaryKey = { id } RETURN n with params {id=PK1}
[main] INFO org.neo4j.ogm.drivers.bolt.request.BoltRequest - Request: MATCH (n) WHERE n.primaryKey = { id } RETURN n with params {id=PK1}
null

Solution

  • Unfortunately this is a bug in OGM. You can raise an issue here : https://github.com/neo4j/neo4j-ogm/issues

    As a workaround, you can declare your index in the Equity class, as OGM only scan leaf classes in the hierarchy for primary indexes.