I am creating a web application in Java and would like to use the Javalin framework.
Issues/questions:
EntityManager
object available to the Javalin request handlers?Update: Some more context
I want to use JPA (via Hibernate) in my javalin application. The central concept in JPA is that you use an EntityManager
instance to access the database. To create an EntityManager
, there is a EntityManagerFactory
.
What I currently do is that I create a global EntityManagerFactory
and the handlers that use the database call factory.createEntityManager()
.
While this works, I wonder if there are other recommended apporaches? Coming from a Flask/SQLAlchemy/Python background - on that stack the ORM session (EntityManager equivalent) is typically available as a request-bound object.
I ended up implementing the following:
EntityManagerFactory
on startup. Create a Javalin
instance on startup. Then call enableRequestBoundEntityManager(javalinApp, entityManagerFactory)
.EntityManager
, use the extension property Context.entityManager
.I.e.:
fun main() {
val app = Javalin.create()
val emf = createEntityManagerFactorySomehow()
enableRequestBoundEntityManager(app, emf)
app.get("/list/") { ctx -> ctx.json(
ctx.entityManager.createQuery("select ... from ...").resultList
) }
app.start()
}
/**
* Adds an `entityManagerFactory` application attribute, and sets up clean up after requests have been handled
*/
fun enableRequestBoundEntityManager(app: Javalin, entityManagerFactory: EntityManagerFactory) {
app.attribute("entityManagerFactory", entityManagerFactory)
app.after {
val entityManager: EntityManager? = it.attribute("entityManager")
if (entityManager != null) {
entityManager.close()
}
}
}
/**
* Returns a JPA entity manager scoped to the Javalin context
*/
val Context.entityManager: EntityManager
get() {
if (this.attribute<EntityManager>("entityManager") == null) {
this.attribute("entityManager", this.appAttribute<EntityManagerFactory>("entityManagerFactory").createEntityManager())
}
return this.attribute("entityManager")!!
}