Squeryl自定义字段类型 [英] Squeryl custom field types

查看:108
本文介绍了Squeryl自定义字段类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆