Problem using an Abstract Facade pattern


#1

I trying to create a JAX-RS application with JPA persistence. It compiles, packages and deploys without errors and the resource layer of the application works, but persistence seems to just stall with no errors logged by the server. I get the same behavior on Payara(Glassfish) and Wildfly. I’m assuming that my Abstract Facade needs rethinking.

abstract class AbstractRepository<E> {

   @PersistenceContext
   lateinit var em: EntityManager

   fun save(e: E) = em.persist(e)

   fun update(e: E) = em.merge(e)

   fun delete(e: E) = em.remove(e)

   inline fun <reified E: Any> find(id: Long) : E = em.find(E::class.java, id)

   inline fun <reified E: Any> list(): List<E> {
        val query = em.criteriaBuilder.createQuery(E::class.java)
        query.select(query.from(E::class.java))
        return em.createQuery(query).resultList
   }
}
...
@Stateless
open class TeamRepository : AbstractRepository<Member>() {}

#2

Does any of the methods (save for example) work? Are your Entity classes open? Have you checked whether the reifcation actually works as expected here?


#3

Sadly none of the methods work and having the entity class as open or a data class has no effect. I even tried to force a persist in an init block. There weird thing is the lack of errors. Maybe it’s a thread starving thing?


#4

This sounds very strange. Have you tried a similar setup with Java? Does it work? I’ve never encountered a Hibernate problem without exceptions. Something seems to be fundamentally broken. Maybe you could create a minimal application to reproduce the problem and share the code with us.


#5

Problem solved! While attempting to create a minimal version I upgraded to newer versions of the Maven war and compiler plugins, replacing the versions in the POM by IntelliJ: Then the errors showed up! I needed to initialize the Entity Manager and lateinit was not enough:

abstract class AbstractRepository<E> {
   @PersistenceContext
   open var em: EntityManager? = null

   fun save(e: E) = em!!.persist(e)

   fun update(e: E) = em!!.merge(e)

   fun delete(e: E) = em!!.remove(e)

   inline fun <reified E: Any> find(id: Long) : E = em!!.find(E::class.java, id)

   inline fun <reified E: Any> list(): List<E> {
        val query = em!!.criteriaBuilder.createQuery(E::class.java)
        query.select(query.from(E::class.java))
        return em!!.createQuery(query).resultList
    }
}

Now everything works! Thanks for all your help!