neo4j-ogm: AutoIndex label NPE during initialization and index lookup

Expected Behavior

All my entity nodes extend an abstract base class called Entity which contains @Id and common methods for all entities. Entity is not annotated with @NodeEntity since I do not want to save its label.

Due to @Id and the new AutoIndex functionality in OGM v3.x, the SessionFactory initialization fails with a NPE during AutoIndex creation. This is caused because @Id is considered a potential index by AutoIndexManager at initialiseIndexMetadata() and since Entity has no label AutoIndex creation throws a NPE.

To solve that I’m now forced to use @NodeEntity in my abstract Entity class, so it contains a valid label to be used during AutoIndex creation. However, I’d except AutoIndex to pick the simple class name as label for the leaf children in the hierarchy. For instance:

Entity --> OtherEntity --> FinalEntity label = FinalEntity where: Entity and OtherEntity are abstractions

NOTE: This behaviour is also suggested on the documentation: https://neo4j.com/docs/ogm-manual/current/tutorial/#tutorial:annotations:graphid

Current Behavior

NPE during AutoIndex creation for label param at: https://github.com/neo4j/neo4j-ogm/blob/master/core/src/main/java/org/neo4j/ogm/autoindex/AutoIndex.java#L66

java.lang.NullPointerException
	at org.neo4j.ogm.autoindex.AutoIndex.createDescription(AutoIndex.java:66)
	at org.neo4j.ogm.autoindex.AutoIndex.<init>(AutoIndex.java:61)
	at org.neo4j.ogm.autoindex.AutoIndexManager.initialiseIndexMetadata(AutoIndexManager.java:72)
	at org.neo4j.ogm.autoindex.AutoIndexManager.<init>(AutoIndexManager.java:57)
	at org.neo4j.ogm.session.SessionFactory.<init>(SessionFactory.java:84)

Possible Solution

It seems the change would be somewhere inside ClassInfo or MetaData. The framework should be capable of checking the hierarchy in between the classes and set the potential indexes to the end classes and all annotated abstract ones.

Steps to Reproduce (for bugs)

  1. Create an abstract Entity with @Id and do not use @NodeEntity
  2. Extend Entity with a second child AnotherEntity class and do not use @NodeEntity
  3. That should be enough to fail during SessionFactory initialization of AutoIndex

Your Environment

  • OGM Version used: 3

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 14
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I have this same bug/issue. I think the bug report is very well written and concise so I have nothing much to add to the report.

To add my +1 to wanting this fixed, I do think it is valid in java to have an AbstactBaseClass for something like Entity. I do think putting fields on such a class is valid and having an id at the level is a common practice. Not wanting every node in the system to have a label like “Entity” also seems like a valid desire. All of this was achievable via prior versions of OGM, but not in this version, which makes the problem seem like a bug.

The issue as Frant points out seems to be that then there cannot be a constraint that works across all sub-types in this case. Perhaps this wasn’t working in old versions and the new behavior is to fail loading in the condition instead of just loading without the constraint. Is that what used to happen? If so, I want that old behavior as an option. Personally, I’d rather live without the constraint (if that was the old behavior) than being forced by the system to not use base-classes, or be forced by the system to add a label for those base classes. Perhaps there is a different set of annotations we should be using to achieve these same ends?

Basically, I think most of us have a class hierarchy with an abstract base class like this :

public abstract class GraphEntity {

    @Id @GeneratedValue
    protected Long graphId;

    // + getters/setters, etc.
}

And regular business classes inheriting that base graph-related class, like so :

@NodeEntity
public class SomeModelClass extends GraphEntity {
    // ...
}

Also, considering Neo4J technical IDs (annotated with @Id) can be reused by Neo4j’s and should not be considered stable over time, we often need to define class-specific, business-oriented IDs. Those IDs will be used a lot in queries, so it makes sense to configure them with @Index(unique=true) :

@NodeEntity
public class Person extends GraphEntity {

    @Index(unique = true)
    protected String ssn; 

    // + other fields, getter/setters, etc.
}

This setup used to work perfectly with previous versions of Neo4j-ogm, but it doesn’t anymore.

Now, trying to put any @Index on business entities throws a NullPointerException during startup. Also, as described by OP, putting the @NodeEntity selectively on the business classes (to avoid ending up with the :GraphEntity label on every single node) does not work anymore.

I’d really appreciate if this bug could be fixed soon, if possible.

Fixed with #514. Will be in OGM 3.1.3.

I just upgraded to ogm 3.x and lost several hours trying to figure out how this @Id stuff is supposed to work. The constraint that @Id annotations must be used in conjunction with @NodeEntity doesn’t make sense from a user perspective. We also have abstract classes that don’t have @NodeEntity annotations but have common id fields and related behaviour. To workaround this, I had to introduce abstract getId() methods, and put @Id fields in all leaf classes, which is ugly as hell.

A posible solution is not define the property Id in the abstract Class and define in all the child classes

@yuniel-acosta What’s “Server Neo4j version 3.0.10”. Do you mean Neo4j OGM 3.1.0?

Apart from that, see my comment on @jdorleans PR.

Bump, there is a PR, please make https://github.com/neo4j/neo4j-ogm/issues/437#issuecomment-380878496 code work. Or even if not accepting please at least update the code to throw a proper error and explain how to work around it.