javahibernatejpajavalin

Using JPA in a Javalin application


I am creating a web application in Java and would like to use the Javalin framework.

Issues/questions:

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.


Solution

  • I ended up implementing the following:

    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")!!
        }