Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
08-09-2022 05:40 AM
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:
Every kind of help, also theoretical will be very appreciated.
Kind Regards
Samuele
Solved! Go to Solution.
08-17-2022 03:21 AM
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.
08-09-2022 06:19 AM
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?
08-09-2022 07:19 AM
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.
08-17-2022 03:21 AM
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.
All the sessions of the conference are now available online