gpt4 book ai didi

java - Spark 使用不可变类和 java (+ lombok) 时出现反序列化错误

转载 作者:行者123 更新时间:2023-12-02 09:08:25 27 4
gpt4 key购买 nike

我有这个简单的模型类

@Value // lombok - create standard all arg constructor and getters
public class ModelA implements Serializable {
private String word;
private double value;
}

这个简单的测试失败了:

public class SparkSerializationTest {

private SparkSession spark = SparkSession.builder()
.master("local")
.appName("Test")
.getOrCreate();

@Test
public void testSerializationModelA() {
ModelA modelA1 = new ModelA("A1", 12.34);
ModelA modelA2 = new ModelA("A2", 56.78);

Dataset<ModelA> dataset = spark.createDataset(
Arrays.asList(modelA1, modelA2),
Encoders.bean(ModelA.class));

List<ModelA> yo = dataset.collectAsList(); // <== *** failure here ***

assertThat(yo).isEqualTo(Arrays.asList(modelA1, modelA2));
}
}

异常(exception):

java.util.concurrent.ExecutionException: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 24, Column 67: failed to compile: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 24, Column 67: No applicable constructor/method found for zero actual parameters; candidates are: "com.xxx.yyy.ModelA(java.lang.String, double)"

它似乎需要一个零参数的构造函数。但我希望我的模型是不可变的,因此具有完整的参数构造函数并且没有 setter 。我该怎么做?

最佳答案

简单的出路

只需为其提供无参数构造函数,无需任何 setter 。它会是可变的,但与提供所有 setter 相比,其困惑程度要稍微低一些。当您使用Kryo作为反序列化器(我认为您已经这样做了)时,您可以将此构造函数保持私有(private)。

全参数构造函数仍然可以使用空值和无意义的值来调用。如果您想对对象的有效性施加一些约定,请显式使用验证。如果您追求的是不变性,那么使用无参数构造函数您的成员将不再是最终的。


对象创建的动态性质

反序列化通过调用最简单的(无参数)构造函数来工作,因为对于所使用的实用程序的作者来说,这是一个更容易实现的过程,而不是将一个调用组装到具有所有必要属性的全参数构造函数,其顺序可以是任意的并且不能保证对对象属性的分配。

相反,他们创建 vanila 对象并通过 setter 或反射填充它,确保序列化版本和对象版本之间的名称匹配。全参数构造函数执行此操作的可靠性较差,并且更难以实现。

在 Kryo 中创建自定义对象

如果您需要保持不变性,则必须使用自定义对象创建。请查看Kryo's example for custom object creation :

Registration registration = kryo.register(SomeClass.class);
registration.setInstantiator(new ObjectInstantiator<SomeClass>() {
public SomeClass newInstance () {
return new SomeClass("some constructor arguments", 1234);
}
});

关于java - Spark 使用不可变类和 java (+ lombok) 时出现反序列化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59609933/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com