Apache Flink:DataSet API外连接中的NullPointerException

时间:2017-10-31 00:25:24

标签: java sql dataset apache-flink

我正在尝试在Flink的数据集API中实现以下简单查询。

select 
    t1_value1 
from  
    table1 
where  
    t1_suppkey not in ( 
        select  
            t2_suppkey
        from  
            table2
     )

所以我的想法是执行一个Left Outer Join(table1.leftOuterJoin(table2)...)然后删除我得到t1_suppkey和t2_suppkey值的所有行。

所以我尝试了这样:

     output = table1
    .leftOuterJoin(table2).where("t1_suppkey").equalTo("t2_suppkey")
    .with((Table1 t1, Table2 t2) -> new Tuple2<>(t1.ps_suppkey, t2.s_suppkey))
    .returns(new TypeHint <Tuple2<Integer, Integer>>() {});

但是,如果我这样做,它总是失败“java.lang.NullPointerException”,我不知道为什么。如果我使用普通的Join而不是Left Outer Join代码可以工作,但这不是我想要的。

我是否需要以不同方式实现Left Join,或者是否有更简单的方法来重写Dataset API中的“not in”语句?

2 个答案:

答案 0 :(得分:0)

DataSet API的外连接也会为内部未找到连接记录的外部记录调用JoinFunction。在这种情况下,the JoinFunction.join() method is called with null

由于您使用的是LEFT OUTER JOIN,因此第二个参数Table2 t2可以是nullNullPointerExceptiont2.s_suppkey引起。您需要检查t2 == null,并且只有t2才能访问{。}}。

您还可以使用FlatJoinFunction参数实现NOT IN联接,Collector参数只有t1才会发出t2 == null

另一种选择是使用Flink的批处理SQL support,它支持您示例中的查询。

答案 1 :(得分:0)

output = table1
.leftOuterJoin(table2)
.where("t1_suppkey").equalTo("t2_suppkey") 
.with((Table1 t1, Table2 t2, Collector<Tuple2<Integer, Integer>> c) -> { 
if(t2 == null) {
    c.collect(new Tuple2<>(t1.t1_suppkey, t1.t1_value1)); 
} 
else { 
    //Do nothing. 
}})