我正在尝试在 Squeryl 中创建自定义字段类型。该字段表示一个Isin 代码,因此它由一个字符串字段支持。按照文档中的示例,我在创建新的 isin 之前添加了一个简单的验证(不管 Isin 代码是什么或验证过程如何工作):
trait Domain[A] { self: CustomType[A] =>
def validate(a: A): Unit
validate(value)
}
class Isin(v: String) extends StringField(v) with Domain[String] {
println("instantiating Isin")
override def validate(s: String) {
println("calling validate with " + s)
assert(checkIsin(s))
}
private def checkIsin(isin: String): Boolean = {
// never mind the exact procedure
}
}
我添加了一些println
以了解发生了什么。我在一个模型中使用这个字段,比如
case class Asset(
val id: Long = 0,
val isin: Isin
) extends KeyedEntity[Long]
object Asset {
import Database.assets
def create(isinCode: String) {
inTransaction {
assets.insert(new Asset(isin = new Isin(isinCode)))
}
}
}
现在,当我调用Asset.create("US0378331005")
(有效的 ISIN)时,我得到了一个异常。在堆栈跟踪中,事实证明此异常是由于对值的init
方法调用引起的null
,该值应该传递给checkIsin
. 确实,println
报表打印
calling validate with US0378331005
Instantiating Isin
calling validate with
所以看起来该validate
方法实际上被调用了两次,但是第二次它得到了一个null
值。
出了什么问题?