Reputation: 1071
I'm trying to implement a JPA query in Play for Scala. I took the information from here, but since the examples are in Java I'm probably mistaken. This is the code:
class ManageBanks @Inject() (jpaApi: JPAApi) extends Controller {
@Transactional
def readMany = {
val em = jpaApi.em
jpaApi.withTransaction( (em: EntityManager) => { // <-- error in this line
val query = em.createQuery("from BankHib order by name")
val list = query.getResultList.asScala.toList.map(_.asInstanceOf[BankHib])
list
})
}
}
I get the following error when I compile:
overloaded method value withTransaction with alternatives: [T](x$1: String, x$2: Boolean, x$3: java.util.function.Supplier[T])T (x$1: Runnable)Unit [T](x$1: java.util.function.Supplier[T])T [T](x$1: String, x$2: Boolean, x$3: java.util.function.Function[javax.persistence.EntityManager,T])T [T](x$1: String, x$2: java.util.function.Function[javax.persistence.EntityManager,T])T [T](x$1: java.util.function.Function[javax.persistence.EntityManager,T])T cannot be applied to (javax.persistence.EntityManager ⇒ List[admin.manage.BankHib])
What's wrong with this code? How to make the query work?
Upvotes: 0
Views: 222
Reputation: 12214
This is because play.db.jpa.JPAApi.withTransaction
has the following signatures:
withTransaction(java.util.function.Function<javax.persistence.EntityManager,T>)
withTransaction(java.lang.String, java.util.function.Function<javax.persistence.EntityManager,T>)
withTransaction(java.lang.String, boolean, java.util.function.Function<javax.persistence.EntityManager,T>)
withTransaction(java.util.function.Supplier<T>)
withTransaction(java.lang.Runnable)
withTransaction(java.lang.String, boolean, java.util.function.Supplier<T>)
.But you are instead passing a Scala function of type (javax.persistence.EntityManager ⇒ List[admin.manage.BankHib])
. So, wrong type and the compiler complains saying that it was not able to find an alternative.
The correct way then is to use a java.util.function.Function[EntityManager, List]
:
class ManageBanks @Inject()(jpaApi: JPAApi) extends Controller {
def readMany = {
jpaApi.withTransaction(new java.util.function.Function[EntityManager, List[BankHib]] {
override def apply(em: EntityManager): List[BankHib] = {
val query = em.createQuery("from BankHib order by name")
query.getResultList.asScala.map(_.asInstanceOf[BankHib]).toList
}
})
}
}
Also, notice that you don't need to mix JPAApi
and JPA
to get an EntityManager
since JPAApi
has methods that already provides it to the given function.
Upvotes: 1
Reputation: 6006
See if this works
class ManageBanks @Inject() (jpaApi: JPAApi) extends Controller {
@Transactional
def readMany = {
jpaApi.withTransaction( () => { // <-- error in this line
val em = JPA.em() // or jpaApi.em
val query = em.createQuery("from BankHib order by name")
val list = query.getResultList.asScala.toList.map(_.asInstanceOf[BankHib])
list
})
}
}
Upvotes: 0