コンパイルエラーがないのに、Slickのコードで実行時にエラーが発生していました。
いろいろ調べてみたのですが、どうやら monadic join
にはjoinできるテーブルに上限があるようです。
monadic joinに関して
細かいことは、今後まとめます。
使い方は2種類。flatMapを使う場合とforを使う場合。
とりあえず、↓がドキュメント
ちなみにこちらのドキュメントでは、implict inner join
と紹介されている
people.flatMap(p => addresses.filter(a => p.addressId === a.id) .map(a => (p.name, a.city)) )
val monadicCrossJoin = for { p <- people a <- addresses } yield (p.name, a.city)
使い方としては、こんな感じになります。
複数のテーブルをjoin!!
使い方がわかればあとは、好きに使うだけ。
複数テーブルを使うときは、↓こんな感じ。
val monadicCrossJoin = for { c <- coffees s <- suppliers p <- people pd <- peopleDetal } yield (c, s, p, pd)
….って使い方をしたいんですが、 実はこれできないんです。
どうやらmonadic join
でjoinできるテーブルには上限があるようなんです。(詳細はこちら)
対応策
じゃあ、一体どうやって4つ以上のテーブルをjoinすればいいの?
対応策は、至極簡単で、そもそもmonadic join
だけで対応するのを諦めることです。
val monadicCrossJoin = for { (c, s) <- coffees.join(suppliers) p <- people pd <- peopleDetal } yield (c, s, p, pd)
↑のような感じで記述すれば問題なく使用できます。
ちょっと説明すると、
val crossJoin = for { (c, s) <- coffees join suppliers } yield (c.name, s.name)
coffees join suppliers
の部分はapplicative join
です。
生成されるSQL文に違いがあり、
monadic join
SELECT c.name, s.name FROM coffees c, suppliers s
applicative join
SELECT c.name, s.name FROM coffees c join suppliers s
となります。
まとめ
バグなのかはいまいちわからないですが、 とりあえず対応策を書いておきました。
参考になれば幸いです。
あと、細かく知ってる方いたら具体的になんでダメなのか教えてもらえるとすごく嬉しい