[在Scala中使用Flink的leftOuterJoinLateral时发生NullPointerException异常

问题描述 投票:1回答:1

我正在尝试遵循the documentation并创建一个表函数来“展平”某些数据。使用joinLateral进行展平时,表函数似乎工作正常,但是使用leftOuterJoinLateral时出现以下错误。我正在使用Scala并尝试了Table API和SQL,但结果相同:

原因:java.lang.NullPointerException:无法将空结果存储在Case类中。

这是我的工作:

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.scala.StreamTableEnvironment
import org.apache.flink.table.api.scala._
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.functions.TableFunction

object example_job{
  // Split the List[Int] into multiple rows
  class Split() extends TableFunction[Int] {
    def eval(nums: List[Int]): Unit = {
      nums.foreach(x =>
        if(x != 3) {
          collect(x)
      })
    }
  }

  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.createLocalEnvironment()
    val tableEnv = StreamTableEnvironment.create(env)
    val splitMe = new Split()

    // Create some dummy data
    val events: DataStream[(String, List[Int])] = env.fromElements(("simon", List(1,2,3)), ("jessica", List(3)))

    val table = tableEnv.fromDataStream(events, 'name, 'numbers)
      .leftOuterJoinLateral(splitMe('numbers) as 'number)
      .select('name, 'number)
    table.toAppendStream[(String, Int)].print()
    env.execute("Flink jira ticket example")
  }
}

当我将.leftOuterJoinLateral更改为.joinLateral时,得到了预期的结果:

(simon,1)
(simon,2)

[使用.leftOuterJoinLateral时,我会期望像:

(simon,1)
(simon,2)
(simon,null) // or (simon, None)
(jessica,null) // or (jessica, None)

似乎这样可能是Scala API的错误?我想先检查一下这里,然后再出票,以防万一我做错事!

scala apache-flink flink-streaming flink-sql
1个回答
1
投票

问题在于,默认情况下,Flink确实希望行的所有字段都不为空。这就是为什么程序在看到外部联接操作的null结果时失败的原因。为了接受null值,您要么需要通过[]禁用null检查,要么

val tableConfig = tableEnv.getConfig
tableConfig.setNullCheck(false)

或者您必须指定结果类型以容许空值,例如指定自定义POJO输出类型:

table.toAppendStream[MyOutput].print()

with

class MyOutput(var name: String, var number: Integer) {
  def this() {
    this(null, null)
  }

  override def toString: String = s"($name, $number)"
}
© www.soinside.com 2019 - 2024. All rights reserved.