eclipse-ee4j / eclipselink

Eclipselink project
https://eclipse.dev/eclipselink/
Other
196 stars 167 forks source link

Lazy connection usage when initalizing an EntityManager #2213

Open KyleAure opened 1 month ago

KyleAure commented 1 month ago

Is your feature request related to a problem? Please describe.

As a user of EclipseLink and OpenLiberty I notice that my application starts slowly because when an EntityManager is created during application start a Connection is made to the Database to initialize the entity manager (see stack below).

at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:322)
at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:158)
at com.ibm.wsspi.persistence.internal.eclipselink.WrappingConnector.connect(WrappingConnector.java:42)
at com.ibm.wsspi.persistence.internal.eclipselink.WrappingConnector.connect(WrappingConnector.java:42)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:173)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:225)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:808)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:270)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:869)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:233)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:340)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:495)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:458)
at com.ibm.wsspi.persistence.internal.PersistenceServiceUnitImpl.createEntityManager(PersistenceServiceUnitImpl.java:106)

This type of eager initialization does not work well when deploying an application in a container environment. An orchestrator needs to verify applications have started as it scales up. Long wait times for application start could cause an orchestrator to over scale to meet demand which can be handled by a fewer number of pods.

Describe the solution you'd like

I would rather my application start fast, and pay the cost of creating a connection when the connection is actually needed (i.e. during the first persist() operation).

Describe alternatives you've considered

None.

Additional context

This feature would also be useful for systems utilizing checkpoint/restore (CRIU) since an entity manager could be initialized in an pipeline environment without access to the production database. A checkpoint taken, and then restored in an environment where the production database is available.

lukasj commented 1 month ago

one should be able to control this through the deploy-on-startup property

KyleAure commented 1 month ago

@lukasj if I am reading that property correctly

eclipselink.deploy-on-startup=false (lazy)(default)

The persistence unit is not initialized until the first EntityManager is created, or until metadata is required from the EntityManagerFactory.

The lazy configuration which is default initializes the persistence unit upon EntityManager creation. What I'm looking for is to wait until the first usage of an EntityManager method that actually needs a connection.