Can't deduce sample value for field of type Option[X[_]]

49 views
Skip to first unread message

John Ryan-Brown

unread,
Dec 17, 2015, 8:19:02 PM12/17/15
to squ...@googlegroups.com
Hi.

Squeryl 0.9.6-RC4 gives an error when trying to deduce a default value for an Option field based on a parameterised type.

Simplified code (without custom type mappers):

case class C[T](i: Int)
trait TestTrait
case class Test(id: Int, c: Option[C[TestTrait]])
object TypeMode extends org.squeryl.PrimitiveTypeMode
import TypeMode._
new Schema() {table[Test]("testTable")}
The creation of the Schema causes an exception to be thrown:
Caused by: java.lang.RuntimeException: class Test used in table testTable, needs a zero arg constructor with sample values for Option[] field c
at org.squeryl.internals.Utils$.throwError(Utils.scala:97)
at org.squeryl.internals.FieldMetaData$$anon$1.build(FieldMetaData.scala:495)
at org.squeryl.internals.PosoMetaData$$anonfun$8.apply(PosoMetaData.scala:118)

 
This seems to be caused by the following code in org.squeryl.internals.FieldMetaData.createDefaultValue: 

case Some(pt: ParameterizedType) => {
pt.getActualTypeArguments.toList match {
case oType :: Nil => {
if(classOf[Class[_]].isInstance(oType)) {
/*
* Primitive types are seen by Java reflection as classOf[Object],
* if that's what we find then we need to get the real value from @ScalaSignature
*/
val trueTypeOption =
if (classOf[Object] == oType && detectScalapOnClasspath()) optionTypeFromScalaSig(member)
else Some(oType.asInstanceOf[Class[_]])
trueTypeOption flatMap { trueType =>
val deduced = createDefaultValue(fieldMapper, member, trueType, None, optionFieldsInfo)
if (deduced != null)
Some(deduced)
else
None //Couldn't create default for type param
}
} else{
None //Type parameter is not a Class
}
}
case _ => None //Not a single type parameter
}
}

The problem seems to be that oType is a java.lang.ParamaterizedType, not a Class, and hence the check "classOf[Class[_]].isInstance(oType)" fails.

One solution would be to alter this check to ensure parameterised types are taken into account.

The workaround I am using is to create a zero-arg constructor for all entity classes which contain an Option field for a parameterised type.

Thanks

John
Reply all
Reply to author
Forward
0 new messages