Squeryl自定义字段类型 [英] Squeryl custom field types
问题描述
我正在尝试在Squeryl中创建自定义字段类型.此字段表示 Isin代码,因此它由字符串字段备份.按照文档上的示例,我在创建新的isin之前添加了一个简单的验证(没关系,什么是Isin代码或验证程序如何工作):
I am trying to create a custom field type in Squeryl. This field represents an Isin code, so it is backed up by a string field. Following the example on the documentation, I have added a simple validation before creating a new isin (never mind what an Isin code is or how the validation procedure works):
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
来找出正在发生的事情.我在类似
I have added some println
to find out what is going on. I use this field inside a model like
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)时,我得到了一个例外.在stacktrace中,发现该异常是由于对null
值的init
方法的调用而导致的,该值应该被传递给checkIsin
.实际上,println
语句会打印
Now, when I call Asset.create("US0378331005")
(a valid ISIN) I get an exception. In the stacktrace it turns out that this exception is due to a call to the init
method on a null
value, which is supposedly passed to checkIsin
. Indeed, the println
statements print
calling validate with US0378331005
Instantiating Isin
calling validate with
因此,似乎validate
方法实际上被调用了两次,但是第二次获得了null
值.
So it seems that the validate
method is actually invoked twice, but the second time it gets a null
value.
出了什么问题?
What is going on wrong?
推荐答案
这里有几个问题.首先,您似乎正在使用提升记录",如果是这种情况,则您是在错误地实现验证逻辑.验证记录字段的正确方法是覆盖
There are several problems here. First off, you seem to be using Lift Record and, if that's the case, you are implementing your validation logic incorrectly. The correct way to validate a Record field is to override
def validations: List[ValidationFunction]
其中ValidationFunction是类型别名
where ValidationFunction is a type alias
type ValidationFunction = ValueType => List[FieldError]
,在您的情况下为ValueType ==字符串.
and in your case ValueType == String.
下一个问题是您的域名特征.因为您对validate的调用已内联到类定义中,所以在构造您的字段时将调用它.显然,此时未设置任何值,因此这就是为什么您看到引用了空值的println的原因.我想象您看到它们的顺序与您的应用程序流程有关.您有一个已验证的现有记录,然后创建了一个新记录,该记录将触发接下来的2条println语句.
The next issue is your Domain trait. Because your call to validate is inlined into the class definition, it will be called when your field is constructed. Obviously there is no value set at that point, so that's why you are seeing the println that references an empty value. I imagine that the order you see them in has something to do with your application flow. You have an existing record that is validated, and after that a new Record is created which triggers the next 2 println statements.
这篇关于Squeryl自定义字段类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!