gpt4 book ai didi

java - 无法使用 Java MongoDB 驱动程序读取或序列化带有枚举的 POJO

转载 作者:行者123 更新时间:2023-11-30 06:14:44 25 4
gpt4 key购买 nike

我有一个现有对象,想要使用 Java + POJO 编解码器在 MongoDB 中序列化。由于某种原因,驱动程序尝试创建枚举实例而不是使用 valueOF:

org.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'phase'. Failed to decode 'value'. Cannot find a public constructor for 'SimplePhaseEnumType'.
at org.bson.codecs.pojo.PojoCodecImpl.decodePropertyModel(PojoCodecImpl.java:192)
at org.bson.codecs.pojo.PojoCodecImpl.decodeProperties(PojoCodecImpl.java:168)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:122)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:126)
at com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52)

枚举:

public enum SimplePhaseEnumType {

PROPOSED("Proposed"),
INTERIM("Interim"),
MODIFIED("Modified"),
ASSIGNED("Assigned");
private final String value;

SimplePhaseEnumType(String v) {
value = v;
}

public String value() {
return value;
}

public static SimplePhaseEnumType fromValue(String v) {
for (SimplePhaseEnumType c: SimplePhaseEnumType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}}

并且该类使用枚举(仅显示相关字段):

public class SpecificPhaseType {

protected SimplePhaseEnumType value;
protected String date;

public SimplePhaseEnumType getValue() {
return value;
}

public void setValue(SimplePhaseEnumType value) {
this.value = value;
}}

我正在寻找一种方法来注释类,以告诉驱动程序在遇到这些字段时使用不同的方法来序列化/反序列化这些字段。我知道如何在序列化/反序列化期间跳过它们,但这并不能解决问题:

public class SpecificPhaseType {

@BsonIgnore
protected SimplePhaseEnumType value;

关于我可以在哪里查看(代码、文档)有什么帮助吗?我已经检查过PojoQuickTour.java , MongoDB Driver Quick Start - POJOsPOJOs - Plain Old Java Objects

谢谢!

--何塞

最佳答案

我想出了该怎么做,你首先需要编写一个自定义编解码器来将枚举读取和写入为字符串(如果你想节省空间,序数是另一种选择,但字符串对我来说已经足够了):

package com.kodegeek.cvebrowser.persistence.serializers;

import com.kodegeek.cvebrowser.entity.SimplePhaseEnumType;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;

public class SimplePhaseEnumTypeCodec implements Codec<SimplePhaseEnumType>{
@Override
public SimplePhaseEnumType decode(BsonReader reader, DecoderContext decoderContext) {
return SimplePhaseEnumType.fromValue(reader.readString());
}

@Override
public void encode(BsonWriter writer, SimplePhaseEnumType value, EncoderContext encoderContext) {
writer.writeString(value.value());
}

@Override
public Class<SimplePhaseEnumType> getEncoderClass() {
return SimplePhaseEnumType.class;
}
}

然后您需要注册新的编解码器,以便 MongoDB 可以使用您的类处理枚举:

/**
* MongoDB could not make this any simpler ;-)
* @return a Codec registry
*/
public static CodecRegistry getCodecRegistry() {
final CodecRegistry defaultCodecRegistry = MongoClient.getDefaultCodecRegistry();
final CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register(packages).build();
final CodecRegistry cvePojoCodecRegistry = CodecRegistries.fromProviders(pojoCodecProvider);
final CodecRegistry customEnumCodecs = CodecRegistries.fromCodecs(
new SimplePhaseEnumTypeCodec(),
new StatusEnumTypeCodec(),
new TypeEnumTypeCodec()
);
return CodecRegistries.fromRegistries(defaultCodecRegistry, customEnumCodecs, cvePojoCodecRegistry);
}

Jackson 使使用 @JsonSerializer/@JsonDeserializer 等注释注册自定义序列化器/反序列化器变得更加容易,而 Mongo 则强制您处理注册表。没什么大不了的:-)

您可以查看完整源代码here 。希望这可以为必须处理类似问题的任何人节省一些时间。

关于java - 无法使用 Java MongoDB 驱动程序读取或序列化带有枚举的 POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49477589/

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