Class JpaServlet
- java.lang.Object
-
- jakarta.servlet.GenericServlet
-
- jakarta.servlet.http.HttpServlet
-
- pl.morgwai.base.servlet.guiced.jpa.JpaServlet
-
- All Implemented Interfaces:
Servlet
,ServletConfig
,Serializable
- Direct Known Subclasses:
SimpleAsyncJpaServlet
public abstract class JpaServlet extends HttpServlet
Base class for servlets that perform other types of time consuming operations apart from JPA. Requests injection of aProvider
<EntityManager
>, its associatedjpaExecutor
and provides some related helper methods:executeWithinTx(Callable)
,removeEntityManagerFromRequestScope()
.- See Also:
SimpleAsyncJpaServlet
, Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected ContextTracker<ContainerCallContext>
containerCallContextTracker
protected jakarta.inject.Provider<EntityManager>
entityManagerProvider
Provides request scopedEntityManager
instances.protected ContextTrackingExecutor
jpaExecutor
Executor associated withentityManagerProvider
's persistence unit.
-
Constructor Summary
Constructors Constructor Description JpaServlet()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static <T> T
executeWithinTx(jakarta.inject.Provider<EntityManager> entityManagerProvider, Callable<T> operation)
Executesoperation
within the DB transaction obtained fromentityManagerProvider
.protected <T> T
executeWithinTx(Callable<T> operation)
Executesoperation
within the DB transaction obtained fromentityManagerProvider
.protected String
getPersistenceUnitBindingName()
Returns injection binding name forentityManagerProvider
andjpaExecutor
in apps that use multiple persistence units.void
init(ServletConfig config)
Requests instances ofentityManagerProvider
andjpaExecutor
from Guice.void
removeEntityManagerFromRequestScope()
Removes the storedEntityManager
from the scope of the current request.-
Methods inherited from class jakarta.servlet.http.HttpServlet
doDelete, doGet, doHead, doOptions, doPost, doPut, doTrace, getLastModified, service, service
-
Methods inherited from class jakarta.servlet.GenericServlet
destroy, getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, log, log
-
-
-
-
Field Detail
-
entityManagerProvider
protected jakarta.inject.Provider<EntityManager> entityManagerProvider
Provides request scopedEntityManager
instances.If a given app uses multiple persistence units, this provider will use the one indicated by
getPersistenceUnitBindingName()
.
-
jpaExecutor
protected ContextTrackingExecutor jpaExecutor
Executor associated withentityManagerProvider
's persistence unit.In apps that use a single persistence unit, this is the same instance as
JpaServletContextListener.mainJpaExecutor
. Otherwise, the one indicated bygetPersistenceUnitBindingName()
.
-
containerCallContextTracker
@Inject protected ContextTracker<ContainerCallContext> containerCallContextTracker
-
-
Method Detail
-
getPersistenceUnitBindingName
protected String getPersistenceUnitBindingName()
Returns injection binding name forentityManagerProvider
andjpaExecutor
in apps that use multiple persistence units.If the app uses a single persistence unit (default,
JpaServletContextListener.isSinglePersistenceUnitApp()
is not overridden and returnstrue
) then this method is never used.By default returns
JpaServletContextListener.MAIN_PERSISTENCE_UNIT_BINDING_NAME
.
If an app that uses multiple persistence units needs to use persistence unit other than the main in some servlet, then this method should be overridden accordingly in that servlet.
-
init
public void init(ServletConfig config) throws ServletException
Requests instances ofentityManagerProvider
andjpaExecutor
from Guice.- Specified by:
init
in interfaceServlet
- Overrides:
init
in classGenericServlet
- Throws:
ServletException
-
executeWithinTx
protected <T> T executeWithinTx(Callable<T> operation) throws Exception
Executesoperation
within the DB transaction obtained fromentityManagerProvider
. Ifoperation
completes normally, commits the transaction. Otherwise the transaction is rolled back.- Throws:
Exception
-
executeWithinTx
public static <T> T executeWithinTx(jakarta.inject.Provider<EntityManager> entityManagerProvider, Callable<T> operation) throws Exception
Executesoperation
within the DB transaction obtained fromentityManagerProvider
. Ifoperation
completes normally, commits the transaction. Otherwise the transaction is rolled back.- Throws:
Exception
-
removeEntityManagerFromRequestScope
public void removeEntityManagerFromRequestScope()
Removes the storedEntityManager
from the scope of the current request.If a given app performs some time consuming operations (such as network communication long CPU/GPU intensive computations etc), that need to be surrounded by JPA operations that do not need to be a part of the same transaction, like for example:
List someRecords = someDbDao.getSomeDataFromDB(); // TX-1 or no TX SomeClass results = someExternalNetworkConnector.someLongOperation(someRecords); someDbDao.storeSomeStatsAboutResults(results); // TX-2
then it may significantly improve performance to close the
EntityManager
after the first (batch of) JPA operation(s) so that other requests may use the underlying connection in the mean time.
In such case, for the second (batch of) JPA operation(s) a newEntityManager
must be obtained. To prevent request-scopedentityManagerProvider
from reusing the old closed one, it needs to be removed from the scope.Note: If a request is handled by multiple threads, care must be taken to prevent some of them from retaining the old stale instance.
-
-