JPA query in Play for Scala throws compilation error - scala

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?

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)
And finally 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.

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

Related

DSL in scala using case classes

My use case has case classes something like
case class Address(name:String,pincode:String){
override def toString =name +"=" +pincode
}
case class Department(name:String){
override def toString =name
}
case class emp(address:Address,department:Department)
I want to create a DSL like below.Can anyone share the links about how to create a DSL and any suggestions to achieve the below.
emp.withAddress("abc","12222").withDepartment("HR")
Update:
Actual use case class may have more fields close to 20. I want to avoid redudancy of code
I created a DSL using reflection so that we don't need to add every field to it.
Disclamer: This DSL is extremely weakly typed and I did it just for fun. I don't really think this is a good approach in Scala.
scala> create an Employee where "homeAddress" is Address("a", "b") and "department" is Department("c") and that_s it
res0: Employee = Employee(a=b,null,c)
scala> create an Employee where "workAddress" is Address("w", "x") and "homeAddress" is Address("y", "z") and that_s it
res1: Employee = Employee(y=z,w=x,null)
scala> create a Customer where "address" is Address("a", "b") and "age" is 900 and that_s it
res0: Customer = Customer(a=b,900)
The last example is the equivalent of writing:
create.a(Customer).where("address").is(Address("a", "b")).and("age").is(900).and(that_s).it
A way of writing DSLs in Scala and avoid parentheses and the dot is by following this pattern:
object.method(parameter).method(parameter)...
Here is the source:
// DSL
object create {
def an(t: Employee.type) = new ModelDSL(Employee(null, null, null))
def a(t: Customer.type) = new ModelDSL(Customer(null, 0))
}
object that_s
class ModelDSL[T](model: T) {
def where(field: String): ValueDSL[ModelDSL2[T], Any] = new ValueDSL(value => {
val f = model.getClass.getDeclaredField(field)
f.setAccessible(true)
f.set(model, value)
new ModelDSL2[T](model)
})
def and(t: that_s.type) = new { def it = model }
}
class ModelDSL2[T](model: T) {
def and(field: String) = new ModelDSL(model).where(field)
def and(t: that_s.type) = new { def it = model }
}
class ValueDSL[T, V](callback: V => T) {
def is(value: V): T = callback(value)
}
// Models
case class Employee(homeAddress: Address, workAddress: Address, department: Department)
case class Customer(address: Address, age: Int)
case class Address(name: String, pincode: String) {
override def toString = name + "=" + pincode
}
case class Department(name: String) {
override def toString = name
}
I really don't think you need the builder pattern in Scala. Just give your case class reasonable defaults and use the copy method.
i.e.:
employee.copy(address = Address("abc","12222"),
department = Department("HR"))
You could also use an immutable builder:
case class EmployeeBuilder(address:Address = Address("", ""),department:Department = Department("")) {
def build = emp(address, department)
def withAddress(address: Address) = copy(address = address)
def withDepartment(department: Department) = copy(department = department)
}
object EmployeeBuilder {
def withAddress(address: Address) = EmployeeBuilder().copy(address = address)
def withDepartment(department: Department) = EmployeeBuilder().copy(department = department)
}
You could do
object emp {
def builder = new Builder(None, None)
case class Builder(address: Option[Address], department: Option[Department]) {
def withDepartment(name:String) = {
val dept = Department(name)
this.copy(department = Some(dept))
}
def withAddress(name:String, pincode:String) = {
val addr = Address(name, pincode)
this.copy(address = Some(addr))
}
def build = (address, department) match {
case (Some(a), Some(d)) => new emp(a, d)
case (None, _) => throw new IllegalStateException("Address not provided")
case _ => throw new IllegalStateException("Department not provided")
}
}
}
and use it as emp.builder.withAddress("abc","12222").withDepartment("HR").build().
You don't need optional fields, copy, or the builder pattern (exactly), if you are willing to have the build always take the arguments in a particular order:
case class emp(address:Address,department:Department, id: Long)
object emp {
def withAddress(name: String, pincode: String): WithDepartment =
new WithDepartment(Address(name, pincode))
final class WithDepartment(private val address: Address)
extends AnyVal {
def withDepartment(name: String): WithId =
new WithId(address, Department(name))
}
final class WithId(address: Address, department: Department) {
def withId(id: Long): emp = emp(address, department, id)
}
}
emp.withAddress("abc","12222").withDepartment("HR").withId(1)
The idea here is that each emp parameter gets its own class which provides a method to get you to the next class, until the final one gives you an emp object. It's like currying but at the type level. As you can see I've added an extra parameter just as an example of how to extend the pattern past the first two parameters.
The nice thing about this approach is that, even if you're part-way through the build, the type you have so far will guide you to the next step. So if you have a WithDepartment so far, you know that the next argument you need to supply is a department name.
If you want to avoid modifying the origin classes you can use implicit class, e.g.
implicit class EmpExtensions(emp: emp) {
def withAddress(name: String, pincode: String) {
//code omitted
}
// code omitted
}
then import EmpExtensions wherever you need these methods

Map key not found error despite using option classes

I'm new to the concept of using the Option type but I've tried to use it multiple places in this class to avoid these errors.
The following class is used to store data.
class InTags(val tag35: Option[String], val tag11: Option[String], val tag_109: Option[String], val tag_58: Option[String])
This following code takes a string and converts it into a Int -> String map by seperating on an equals sign.
val message= FIXMessage("8=FIX.4.29=25435=D49=REDACTED56=REDACTED115=REDACTED::::::::::CENTRAL34=296952=20151112-17:11:1111=Order7203109=CENTRAL1=TestAccount63=021=155=CSCO48=CSCO.O22=5207=OQ54=160=20151112-17:11:1338=5000040=244=2815=USD59=047=A13201=CSCO.O13202=510=127
")
val tag58 = message.fields(Some(58)).getOrElse("???")
val in_messages= new InTags(message.fields(Some(35)), message.fields(Some(11)), message.fields(Some(109)), Some(tag58))
println(in_messages.tag_109.getOrElse("???"))
where the FIXMessage object is defined as follows:
class FIXMessage (flds: Map[Option[Int], Option[String]]) {
val fields = flds
def this(fixString: String) = this(FIXMessage.parseFixString(Some(fixString)))
override def toString: String = {
fields.toString
}
}
object FIXMessage{
def apply(flds: Map[Option[Int], Option[String]]) = {
new FIXMessage(flds)
}
def apply(flds: String) = {
new FIXMessage(flds)
}
def parseFixString(fixString: Option[String]): Map[Option[Int], Option[String]] = {
val str = fixString.getOrElse("str=???")
val parts = str.split(1.toChar)
(for {
part <- parts
p = part.split('=')
} yield Some(p(0).toInt) -> Some(p(1))).toMap
}
}
The error I'm getting is ERROR key not found: Some(58) but doesnt the option class handle this? Which basically means that the string passed into the FIXMessage object doesnt contain a substring of the format 58=something(which is true) What is the best way to proceed?
You are using the apply method in Map, which returns the value or throw NoSuchElementException if key is not present.
Instead you could use getOrElse like
message.fields.getOrElse(Some(58), Some("str"))

scala method implicit convertion not working

I have a Play 2.3 project with custom headers coming from AJAX that need to be passed to every service call (to be passed further to the web services). I thought about making it an implicit parameter, like in this dumbed down example :
case class CriteriaHeaders(license: String)
case class Criteria(criteriaHeaders: CriteriaHeaders, id: Int)
class ProjectController(service: Service) {
implicit def criteriaToCiteriaHeaders(criteria: Criteria): CriteriaHeaders = criteria.criteriaHeaders
def findName(criteria: Criteria) = {
// implicit val criteriaHeaders: CriteriaHeaders = criteria.criteriaHeaders
service
.findName(criteria.id)
.fold(
error => error,
name => name
)
}
}
class Service {
def findName(id: Int)
(implicit criteriaHeaders: CriteriaHeaders): Either[String, String] = ??? // TODO
}
(Of course in the real project there is an ActionBuilder, a Json parser etc.)
Usage :
val controller = new ProjectController(new Service())
val name = controller.findName(Criteria(CriteriaHeaders("abc"), 123))
It doesn't compile, giving an error :
Error:(21, 17) could not find implicit value for parameter licenseHeaders: A$A172.this.CriteriaHeaders.findName(criteria.id)
However, if I uncomment the implicit val, it works. Why it doesn't work with the implicit method?
EDIT :
In case anyone find this useful, I took second suggestion from #till-rohrmann and I put the implicit in the companion object of the CriteriaHeaders, so it is available in every controller using it.
object CriteriaHeaders {
implicit def criteriaToCiteriaHeaders(implicit criteria: Criteria) = criteria.criteriaHeaders
}
The problem is that an implicit conversion which takes an explicit parameter won't be called to obtain the implicit argument for the Service.findName method. There are two solutions to your problem.
Call the findName method with an explicit second parameter list and the Criteria argument. Then the compiler knows that it has to convert the criteria value into a CriteriaHeaders.
class ProjectController(service: Service) {
implicit def criteriaToCriteriaHeaders(criteria: Criteria): CriteriaHeaders = criteria.criteriaHeaders
def findName(criteria: Criteria) = {
service
.findName(criteria.id)(criteria)
.fold(
error => error,
name => name
)
}
}
Make the parameter criteria of ProjectController.criteriaToCriteriaHeaders and ProjectController.findName implicit. Then the implicit conversion will be used.
class ProjectController(service: Service) {
implicit def criteriaToCiteriaHeaders(implicit criteria: Criteria): CriteriaHeaders = criteria.criteriaHeaders
def findName(implicit criteria: Criteria) = {
service
.findName(criteria.id)
.fold(
error => error,
name => name
)
}
}

Scala Reflection Conundrum: Can you explain these weird results?

I wrote some Scala code, using reflection, that returns all vals in an object that are of a certain type. Below are three versions of this code. One of them works but is ugly. Two attempts to improve it don't work, in very different ways. Can you explain why?
First, the code:
import scala.reflect.runtime._
import scala.util.Try
trait ScopeBase[T] {
// this version tries to generalize the type. The only difference
// from the working version is [T] instead of [String]
def enumerateBase[S: universe.TypeTag]: Seq[T] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[T])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
}
trait ScopeString extends ScopeBase[String] {
// This version works but requires passing the val type
// (String, in this example) explicitly. I don't want to
// duplicate the code for different val types.
def enumerate[S: universe.TypeTag]: Seq[String] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
// This version tries to avoid passing the object's type
// as the [S] type parameter. After all, the method is called
// on the object itself; so why pass the type?
def enumerateThis: Seq[String] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[this.type].decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
}
// The working example
object Test1 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerate[Test1.type]
}
// This shows how the attempt to generalize the type doesn't work
object Test2 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateBase[Test2.type]
}
// This shows how the attempt to drop the object's type doesn't work
object Test3 extends ScopeString {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateThis
}
val test1 = Test1.fields // List(test)
val test2 = Test2.fields // List(13, test)
val test3 = Test3.fields // List()
The "enumerate" method does work. However, as you can see from the Test1 example, it requires passing the object's own type (Test1.type) as a parameter, which should not have been necessary. The "enumerateThis" method tries to avoid that but fails, producing an empty list. The "enumerateBase" method attempts to generalize the "enumerate" code by passing the val type as a parameter. But it fails, too, producing the list of all vals, not just those of a certain type.
Any idea what's going on?
Your problem in your generic implementation is the loss of the type information of T. Also, don't use exceptions as your primary method of control logic (it's very slow!). Here's a working version of your base.
abstract class ScopeBase[T : universe.TypeTag, S <: ScopeBase[T, S] : universe.TypeTag : scala.reflect.ClassTag] {
self: S =>
def enumerateBase: Seq[T] = {
val mirror = currentMirror.reflect(this)
universe.typeOf[S].baseClasses.map(_.asType.toType).flatMap(
_.decls
.filter(_.typeSignature.resultType <:< universe.typeOf[T])
.filter(_.isMethod)
.map(_.asMethod)
.filter(_.isAccessor)
.map(decl => mirror.reflectMethod(decl).apply().asInstanceOf[T])
.filter(_ != null)
).toSeq
}
}
trait Inherit {
val StringField2: String = "test2"
}
class Test1 extends ScopeBase[String, Test1] with Inherit {
val IntField: Int = 13
val StringField: String = "test"
lazy val fields = enumerateBase
}
object Test extends App {
println(new Test1().fields)
}
Instead of getting the type from universe.typeOf you can use the runtime class currentMirror.classSymbol(getClass).toType, below is an example that works:
def enumerateThis: Seq[String] = {
val mirror = currentMirror.reflect(this)
currentMirror.classSymbol(getClass).toType.decls.map {
decl => Try(mirror.reflectField(decl.asMethod).get.asInstanceOf[String])
}.filter(_.isSuccess).map(_.get).filter(_ != null).toSeq
}
//prints List(test)
With everyone's help, here's the final version that works:
import scala.reflect.runtime.{currentMirror, universe}
abstract class ScopeBase[T: universe.TypeTag] {
lazy val enumerate: Seq[T] = {
val mirror = currentMirror.reflect(this)
currentMirror.classSymbol(getClass).baseClasses.map(_.asType.toType).flatMap {
_.decls
.filter(_.typeSignature.resultType <:< universe.typeOf[T])
.filter(_.isMethod)
.map(_.asMethod)
.filterNot(_.isConstructor)
.filter(_.paramLists.size == 0)
.map(decl => mirror.reflectField(decl.asMethod).get.asInstanceOf[T])
.filter(_ != null).toSeq
}
}
}
trait FieldScope extends ScopeBase[Field[_]]
trait DbFieldScope extends ScopeBase[DbField[_, _]] {
// etc....
}
As you see from the last few lines, my use cases are limited to scope objects for specific field types. This is why I want to parameterize the scope container. If I wanted to enumerate the fields of multiple types in a single scope container, then I would have parameterized the enumerate method.

Specs2: Use a Hamcrest matcher

I have a wide array of Hamcrest matchers for my domain objects written in Java.
I'm now moving to Scala and would like to reuse these existing matchers in the context of specs2 tests.
Given a Hamcrest matcher for class Foo:
public class FooMatcher extends TypeSafeMatcher[Foo] {
...
}
I'd like to be able to use it thus:
val myFooMatcher = new FooMatcher(...)
foo must match (myFooMatcher)
foos must contain (myFooMatcher1, myFooMatcher2)
And so on.
Specs2 seems to have the opposite, an adapter of its Matcher[T] trait to org.hamcrest.Matcher, but I'm looking for the other way around.
Any ideas?
You need to add one implicit conversion for this to work:
import org.hamcrest._
import org.specs2.matcher.MustMatchers._
implicit def asSpecs2Matcher[T](hamcrest: org.hamcrest.TypeSafeMatcher[T]):
org.specs2.matcher.Matcher[T] = {
def koMessage(a: Any) = {
val description = new StringDescription
description.appendValue(a)
hamcrest.describeTo(description)
description.toString
}
(t: T) => (hamcrest.matches(t), koMessage(t))
}
Let's see it in action:
case class Foo(isOk: Boolean = true)
// a Hamcrest matcher for Foo elements
class FooMatcher extends TypeSafeMatcher[Foo] {
def matchesSafely(item: Foo): Boolean = item.isOk
def describeTo(description: Description) = description.appendText(" is ko")
}
// an instance of that matcher
def beMatchingFoo = new FooMatcher
// this returns a success
Foo() must beMatchingFoo
// this returns a failure
Foo(isOk = false) must beMatchingFoo
// this is a way to test that some elements in a collection have
// the desired property
Seq(Foo()) must have oneElementLike { case i => i must beMatchingFoo }
// if you have several matchers you want to try out
Seq(Foo()) must have oneElementLike { case i =>
i must beMatchingFoo and beMatchingBar
}