当前位置: 首页 > 知识库问答 >
问题:

使用泛型类型为Java POJO生成Avro模式

徐丰茂
2023-03-14

我正在尝试使用以下方法在运行时获取Avro模式:

private Schema getSchema(Class clazz) {
    Schema s = ReflectData.get().getSchema(clazz);
    AvroSchema avroSchema = new AvroSchema(s);
    return avroSchema.getAvroSchema();
  }

但由于我的POJO类包含以下泛型:

public abstract class Data<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private String dataType;
    private T id;

    public Data() {
    }

    public Data(String dataType) {
        this.dataType = dataType;
    }

    public Data(String dataType, T id) {
        this.dataType = dataType;
        this.id = id;
    }
}

我得到以下例外情况:

Exception in thread "main" org.apache.avro.AvroRuntimeException: avro.shaded.com.google.common.util.concurrent.UncheckedExecutionException: org.apache.avro.AvroTypeException: Unknown type: T
    at org.apache.avro.specific.SpecificData.getSchema(SpecificData.java:227)

我知道Avro不会支持泛型类型。是否有一种方法可以在运行时生成架构时从类中省略某些类字段?

共有1个答案

季嘉良
2023-03-14
private <T> String writePojoToParquet(List<T> pojos, String fileKey){
        String fileName = fileKey + ".parquet";
        Path path = new Path(fileName.replace("/", "_"));
        //No matter what delete file always.
        String strPath = path.toString();
        FileUtils.delete(strPath);
        FileUtils.delete(strPath + ".crc");
        logger.debug("Writing data to parquet file {}", strPath);
        Configuration conf = new Configuration();
        try (ParquetWriter<T> writer =
                     AvroParquetWriter.<T>builder(path)
                             .withSchema(ReflectData.AllowNull.get().getSchema(pojos.get(0).getClass()))
                             .withDataModel(ReflectData.get())
                             .withConf(conf)
                             .withCompressionCodec(CompressionCodecName.SNAPPY)
                             .withWriteMode(ParquetFileWriter.Mode.OVERWRITE)
                             .enableValidation()
                             .enableDictionaryEncoding()
                             .build()) {
            for (T p : pojos) {
                writer.write(p);
            }
            return strPath;
        } catch (IOException e) {
            logger.error("Error while writing data to parquet file {}.", strPath, e);
        }
        return null;
    }
 类似资料:
  • 我有一个带有日期的简单POJO,在导入Google BigQuery之前,它将作为Avro存储在存储器中。日期转换为long,我试图使用@AvroSchema覆盖日期字段的模式生成,以便BigQuery了解字段的类型。 简单的POJO: 这最终得到以下AVRO-Schema: 这些似乎是错误的,应该是简单的{“name”:“tm”,“type”:“long”,“logicalType”:“time

  • 我在父类和子类中都有构建器。父对象有一个抽象生成器和一个扩展抽象生成器的具体生成器。子级有一个扩展父级抽象生成器的抽象生成器和一个扩展子级抽象生成器的具体生成器。原因是父级的setter返回当前的Builder类。我有一些方法返回类自己的抽象构建器类型,我想将其称为父抽象类型(调用它的父方法)。我所能做的就是

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 如何为动态创建的函数声明泛型类型? 我如何在中使用并传递? < code>useFoo的预期用法

  • 我想使用泛型类作为另一个泛型类的类型参数。 起初,我对类的定义是这样的: 然后我的需求发生了变化,我不得不为我的R类型使用包装器/持有者类 到目前为止,我的尝试:(给出编译时错误:

  • Spring4包含了对泛型类型解析的主要增强,但当包含bean类的type参数被参数化时,我无法自动生成泛型类型。 我需要跟踪提交给外部服务的作业的状态,并且我想在每个作业启动时为其创建一个条目,并在收到回发时清除或更新它。我通常会尝试将持久性策略与服务接口分开,因此我有一个接口,一个Spring数据Mongo类。由于作业可能会在外部服务有机会为其分配ID(例如HTTP 502)之前失败,因此我需