cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

OGM fixed delay of 1sec.

Hi to All,
I recently tried to adopt Neo4j as a DBMS for a "typical" 3-tier architecture in Java, adopting the OGM library (vers. 3.2.36).

In first place, I want to outline that the project adopts the JEE stack, with JAX-RS for realizing REST services; so I'm not using Spring or Spring Data Neo4j.

I noticed (sampling performance of the session component) that my queries always take more than 1 second while the same queries on the neo4j browser usually take 20ms (the same happens using directly the HTTP API). This happens with every kind of FIRST interaction through the session component both with HTTP and BOLT drivers. A second interaction on the same instantiated Session is not affected by this issue and takes 20ms in average.

Now I understand that the instantiation of the Session component through the factory may be heavy but the overhead seems to me too impacting.

I also read the guide searching for the right strategy for long-living or reusing the Session component instance for optimizations, founding that "a Session should correspond to a unit of work in your application" which is almost the definition of REST service. I was, indeed, creating one Session per HTTP Request received by the server.

So, the questions are:

  1. Is it credible to have an overhead of 1 second for each Session instantiation? Am I doing something wrong or missing some configurations?
  2. Is Neo4j OGM designed for RESTful and stateless architectures or do we have to find hybrid approaches?
  3. Which can be a good alternative approach?

Every kind of help, also theoretical will be very appreciated.

Kind Regards
Samuele

1 ACCEPTED SOLUTION

Your are using EJB's Singleton here. There is a paragraph about no-arg constructors and no-interface classes in the EJB 3.1 reference (3.4.4) https://jcp.org/aboutJava/communityprocess/mrel/jsr318/index3.html

Most important quote:

"The developer of an enterprise bean that exposes a no-interface view must not make any assumptions about the number of times the bean class no-arg constructor will be called. For example, it is possible that the acquisition of a client reference to the no-interface view will result in the invocation of thebean-class constructor. It is recommended that the bean developer place component initialization logic in a @PostConstruct method instead of the bean class no-arg constructor."

This means that every time you call the supposed-to-be-singleton class, the constructor might get called. Those behaviour will trigger the expensive driver creation again and again.

View solution in original post

3 REPLIES 3

Do you use any object graph mapping? If not you can also use the plain driver (but make sure to instantiate the driver only once per application lifetime)

Can you share the code where you create the OGM sessions? Can you make sure in your JEE app the driver is instantiated as singleton, not for every request?

Thank you, Michael.

Yes, I'm using the OGM library in its vers. 3.2.36 within a Maven project.

I think it may be not so simple to show the whole code of my JEE architecture in so that it's distributed in various components with different responsibilities.

You said something interesting for me, the need for a singleton instance of the Driver. Then, I used EJB for realizing a Singleton of the Factory, as follows:


import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;

import javax.ejb.Singleton;

@Singleton
public class GraphSessionFactory {

    private SessionFactory sessionFactory;

    public GraphSessionFactory() {
        Configuration configuration = new Configuration.Builder()
                //.uri("http://localhost:7474/")
                .uri("bolt://127.0.0.1:7687")
                .database("neo4j")
                .credentials("neo4j", "password")
                .connectionPoolSize(150)
                .build();

        this.sessionFactory = new SessionFactory(configuration, "...my domain model package ..");
    }

    public Session createSession() {
        return this.sessionFactory.openSession();
    }
}

 In this way, the SessionFactory is effectively a Single instance within a Singleton component. I do no see everything else about the Driver except for the Configuration itself. Am I right?

Just for explaining how I'm using this, I call the createSession one time for each REST service if it is necessary and I use the single Session instance for the whole HTTP request.

Your are using EJB's Singleton here. There is a paragraph about no-arg constructors and no-interface classes in the EJB 3.1 reference (3.4.4) https://jcp.org/aboutJava/communityprocess/mrel/jsr318/index3.html

Most important quote:

"The developer of an enterprise bean that exposes a no-interface view must not make any assumptions about the number of times the bean class no-arg constructor will be called. For example, it is possible that the acquisition of a client reference to the no-interface view will result in the invocation of thebean-class constructor. It is recommended that the bean developer place component initialization logic in a @PostConstruct method instead of the bean class no-arg constructor."

This means that every time you call the supposed-to-be-singleton class, the constructor might get called. Those behaviour will trigger the expensive driver creation again and again.

Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online