Flink代码执行报错Cannot reference field by field expression on GenericType

文章讲述了在ApacheFlink中遇到的一个错误,该错误指出Flink的sum算子不支持对非POJO类型的字段进行操作。具体来说,问题出在尝试对内部类Sensor使用sum函数,而Flink要求POJO类型、元组或caseclasses才能使用字段表达式。解决方案是将Sensor类改为公共类以符合POJO规范。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

详细报错信息

Exception in thread "main" org.apache.flink.api.common.typeutils.CompositeType$InvalidFieldReferenceException: Cannot reference field by field expression on GenericType<myflink.windows.Sensor>Field expressions are only supported on POJO types, tuples, and case classes. (See the Flink documentation on what is considered a POJO.)
	at org.apache.flink.streaming.util.typeutils.FieldAccessorFactory.getAccessor(FieldAccessorFactory.java:193)
	at org.apache.flink.streaming.api.functions.aggregation.SumAggregator.<init>(SumAggregator.java:55)
	at org.apache.flink.streaming.api.datastream.KeyedStream.sum(KeyedStream.java:749)
	at myflink.windows.TimeWindows.main(TimeWindows.java:42)

上述报错含义为:Flink sum算子只支持对POJO types, tuples, and case classes使用field进行声明,代码中自定义了类,但不是POJO types,因此报错。

错误代码如下:

package myflink.windows;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.datastream.WindowedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.assigners.WindowAssigner;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.streaming.api.windowing.windows.Window;
import org.apache.flink.util.Collector;

/**
 * @projectName: my-flink-project
 * @package: myflink.windows
 * @className: TimeWindows
 * @author: fangjiayueyuan
 * @description: TODO
 * @date: 2023/5/31 11:34 PM
 * @version: 1.0
 */
public class TimeWindows {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<String> ds = env.socketTextStream("localhost", 9000);
        SingleOutputStreamOperator<Sensor> map = ds.map(new MapFunction<String, Sensor>() {
            @Override
            public Sensor map(String s) throws Exception {
                String[] arr = s.split(",");
                return new Sensor(arr[0], Integer.parseInt(arr[1]));

            }
        });
        SingleOutputStreamOperator<Sensor> count = map.keyBy(Sensor::getSensorId).sum("count").returns(TypeInformation.of(Sensor.class));
        count.print();
        env.execute();
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Sensor {
    private String sensorId;
    private  Integer count;
}

其中Sensor是内部类,不符合POJO types的定义。

什么是POJO types?

Flink 会分析那些不属于任何一类的数据类型,尝试将它们作为 POJO 类型进行处理。如果一个类型满足如下条件,Flink 就会将它们作为 POJO 数据类型:

POJOs 类必须是一个公有类,Public 修饰且独立定义,不能是内部类;
POJOs 类中必须包含一个 Public 修饰的无参构造器;
POJOs 类中所有的字段必须是 Public 或者具有 Public 修饰的 getter 和 setter 方法;
POJOs 类中的字段类型必须是 Flink 支持的。

如何修改

把Sensor类构建成public类即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值