Squeryl custom field types

2019-10-29 12:39发布

我试图创建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值。

什么是错的怎么回事?

Answer 1:

这里有几个问题。 首先,你似乎可以用电梯记录,如果是那样的话,你是不正确实现您的验证逻辑。 验证一个记录字段的正确方法是重写

def validations: List[ValidationFunction]

其中ValidationFunction是一个类型别名

type ValidationFunction = ValueType => List[FieldError]

对你来说值类型==字符串。

接下来的问题是,你的域特征。 因为你的电话验证的内联到类的定义,当你的场构造就会被调用。 显然,没有设置在该点的值,所以这就是为什么你看到它引用一个空值的println。 我想,你看到他们在为了有事情做与你的应用程序流。 您有验证的现有记录,而一个新的记录在创建后触发未来2个println语句。



文章来源: Squeryl custom field types
标签: scala squeryl