0

Problem when using Slick to join: I have 2 tables User and UserInfo and I want to leftJoin them to get user's info. I've tried this:

val q = for{
  (user,info) <- User leftJoin UserInfo on (_.id === _.userid)
} yield(user, info)

But the UserInfo table has some nullable field, so when I try to execute the query:

q.map(user_info => (user_info._1,user_info._2)).list

It makes error because user_info._2 has some null values. I know a solution that yield each field in UserInfo and add getOrElse(None) for nullable fields. However, UserInfo has many field so I don't want to use this.

Can anyone help me?

Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • 1
    If the nullable fields are defined as `Option`s in the schema they will be returned so, I suspect your problem is elsewhere, for example what kind of exception are you getting exactly? How is your schema defined? – Ende Neu Jul 03 '14 at 07:30
  • `x.getOrElse(None)` should be exactly the same as `x`, right? How could that solve your problem? – Dan Getz Jul 03 '14 at 10:11
  • Duplicate of http://stackoverflow.com/q/20386593/ and http://stackoverflow.com/q/14990365 – Dan Getz Jul 03 '14 at 10:24

1 Answers1

2

What you CAN do, is this define a function that does the conversion, and then use it in your map:

def nullToOption[A](input: A): Option[A] = input match {
  case null => None
  case x    => Some(x)
}

And then you just use it in your map.

I made a simple example using a simple list:

val lst = List("Hello", null, "hi", null)

val newlst = map lst nullToOption

newList is now the following: List(Some("Hello"), None, Some("hi"), None)

Of course you can modify nullToOption to fit your needs; here's a version that takes tuples:

def nullToOption[A, B](input: (A,B)): (Option[A], Option[B]) = input match {
  case (x, y)       => (Some(x), Some(y))
  case (x, null)    => (Some(x), None)
  case (null, y)    => (None, Some(y))
  case (null, null) => (None, None)
}
Electric Coffee
  • 11,733
  • 9
  • 70
  • 131