【问题标题】:Unexpected Nullable Found after left join左连接后发现意外的 Nullable
【发布时间】:2014-03-02 03:37:30
【问题描述】:

我在使用 Play 开发 Web 应用程序时遇到了一些小问题!框架、Scala 和 Anorm 与 Mysql。

我有这两个案例类:

case class Supplier(id : Pk[Long]= NotAssigned,
         identityId : Option[SupplierIdentity], 
         addressId : Option[Address], userId : User) {}

object Supplier {
      val simple = {
        get[Pk[Long]]("Supplier.id") ~
        SupplierIdentity.simple ~
        Address.simple ~
        User.simple map {
          case id ~ identityId ~ addressId~ userId => 
               Supplier(id, Some(identityId), Some(addressId), userId)
        }

case class Address(id : Pk[Long] = NotAssigned, via : String, cap : Int, comune : String, provincia : String, paese : String) {

}

object Address {

    val simple = {
            get[Pk[Long]]("Address.id") ~
            get[String]("Address.via") ~
            get[Int]("Address.cap") ~
            get[String]("Address.comune") ~
            get[String]("Address.provincia") ~
            get[String]("Address.paese") map {
            case id ~ via ~ cap ~ comune ~ provincia ~ paese=> 
            Address(id, via ,cap , comune , provincia , paese)
            }
    }

在尝试检索供应商时,我有这个查询来访问我的数据库:

def findByIdentity(identityId: Long) : Option[Supplier]= {
      DB.withConnection {implicit connetion =>
      SQL("""SELECT * 
          FROM Supplier 
          LEFT JOIN SupplierIdentity 
          ON Supplier.identity_id= SupplierIdentity.id  
          LEFT OUTER JOIN Address
          ON Supplier.address_id= Address.id   
          LEFT JOIN User 
          ON Supplier.user_id= User.id 
          WHERE Supplier.identity_id={id}""").on('id->identityId).as(Supplier.simple.singleOpt)
    }
   }

而且我确信它可以工作,因为我已经在 Mysql 服务器上尝试过,它可以使用正确的值:

id | identity_id | address_id | user_id | id   | supplier_code | type | ragione_sociale | partita_iva | is_production | id   | via  | cap  | comune | provincia | paese | id   | name    |
+----+-------------+------------+---------+------+---------------+------+-----------------+-------------+---------------+------+------+------+--------+-----------+-------+------+---------+
|  2 |           2 |       NULL |       1 |    2 |             1 | q    | q               |           1 |             1 | NULL | NULL | NULL | NULL   | NULL      | NULL  |    1 | Tiziano |

但是当我尝试从我的控制器中使用此方法时,我收到此错误:

[运行时异常: UnexpectedNullableFound(ColumnName(Address.id,Some(id)))]

这是我的问题,因为这些列可能为空,但我找不到处理空值的方法。我希望 wuery 能够正常工作,即使它的某些列为空。 你能给我一些建议吗?

【问题讨论】:

    标签: mysql scala playframework-2.0


    【解决方案1】:

    由于您使用的是左连接,因此解析器应该是可选的,如下所示:

    case class Supplier(id : Pk[Long]= NotAssigned,
         identityId : Option[SupplierIdentity], 
         addressId : Option[Address], userId : User) {}
    
    object Supplier {
      val simple = {
        get[Pk[Long]]("Supplier.id") ~
        (SupplierIdentity.simple ?) ~
        (Address.simple ?) ~
        (User.simple ?) map {
          case id ~ identityId ~ addressId~ userId => 
               Supplier(id, identityId, addressId, userId)
    }
    

    似乎userId 也应该是Option[User],因为您已加入。如果它不是可选的,它应该是一个内部连接(使用原始解析器),否则你会遇到同样的问题。发生这种情况的原因是左连接保留了所有这些空列,但您的解析器正在寻找非空值。 Address.simple ? 将解析为Option[Address],当找不到整个模型时将解析为None

    【讨论】:

    • 这正是我的问题。只是为了纠正,如果有人有同样的问题,你必须从 Supplier(id, Some(identityId), Some(addressId), userId) 中删除“一些”,所以它变成了 Supplier(id, identityId, addressId, userId) 和它完美地工作。你是对的 LimbSoup,用户将以相同的方式实现(但我现在不在乎)
    • 对。只是忽略了这一点。
    猜你喜欢
    • 1970-01-01
    • 2014-12-10
    • 2011-10-01
    • 1970-01-01
    • 2016-11-23
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    相关资源
    最近更新 更多