Search code examples
jakarta-eeneo4jspring-data-neo4jgraphaware

Initialize other variables from @Context injected variable


I have a problem in implementing neo4j Graphaware solution. Previously I was creating the GraphDatabaseService object like the following -

public class TimetreeUtil {
    public static GraphDatabaseService db;
    public static SingleTimeTree st;
    public static TimeTreeBackedEvents ttbe;
    public static TimeTreeBusinessLogic ttbl;
    public static TimedEventsBusinessLogic tebl;    
    public static List<Event> eventsFetchedFromTimetree;

    public TimetreeUtil() {
        db =  new GraphDatabaseFactory( ).newEmbeddedDatabase(new File("..."));
        st = new SingleTimeTree(db);
        ttbl = new TimeTreeBusinessLogic(db);
        ttbe = new TimeTreeBackedEvents(st);
        tebl = new TimedEventsBusinessLogic(db, ttbe);
    }
}

This was working fine. As you can see that GraphDatabaseService, SingleTimeTree, TimeTreeBackedEvents, TimeTreeBusinessLogic and TimedEventsBusinessLogic - all are static and they should be, because neo4j demands that.

But now our architecture has changed and we are injecting the GraphDatabaseService by -

@Context
public GraphDatabaseService db;

So now the class looks like -

public class TimetreeUtil {
        @Context
        public GraphDatabaseService db;
        public static SingleTimeTree st;
        public static TimeTreeBackedEvents ttbe;
        public static TimeTreeBusinessLogic ttbl;
        public static TimedEventsBusinessLogic tebl;    
        public static List<Event> eventsFetchedFromTimetree;

        public TimetreeUtil() {
            st = new SingleTimeTree(db);
            ttbl = new TimeTreeBusinessLogic(db);
            ttbe = new TimeTreeBackedEvents(st);
            tebl = new TimedEventsBusinessLogic(db, ttbe);
        }
    }

The helper class Timetree is just creating an object of the the TimetreeUtil class by TimetreeUtil util = new TimetreeUtil(); and then calling one method of TimetreeUtil.

I am assuming that by the time the constructor is called, db would have been already initialized, but it's not. db is null and hence st = new SingleTimeTree(db); is giving NPE.

How can I meet both the ends meet? Thanks.


Solution

  • Dependency injection runs after the object is created - Java has to create the object before the object instance variables can be set - hence the NPE.

    You may be able to pass the object in the constructor (worth testing but i'm not sure it will work):

        private GraphDatabaseService db;
        public static SingleTimeTree st;
        public static TimeTreeBackedEvents ttbe;
        public static TimeTreeBusinessLogic ttbl;
        public static TimedEventsBusinessLogic tebl;    
        public static List<Event> eventsFetchedFromTimetree;
    
        public TimetreeUtil(@Context GraphDatabaseService db) {
            this.db = db
            st = new SingleTimeTree(db);
            ttbl = new TimeTreeBusinessLogic(db);
            ttbe = new TimeTreeBackedEvents(st);
            tebl = new TimedEventsBusinessLogic(db, ttbe);
        }