Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Micronaut注册MongoDB的编解码器_Java_Mongodb_Micronaut - Fatal编程技术网

Java 使用Micronaut注册MongoDB的编解码器

Java 使用Micronaut注册MongoDB的编解码器,java,mongodb,micronaut,Java,Mongodb,Micronaut,我正在使用Micronaut和MongoDB创建一个新的应用程序。关于我的一些db对象,我不得不有点僵持 我有一个对象,其中包含一个枚举字段,我需要将其转换为可以保存的值(我计划将其作为字符串保存) 根据我的理解和收到的错误消息,我需要创建一个新的编解码器来处理这个问题(类似于JPA转换器)。虽然我已经找到了显示这一点的示例,但对于如何为MongoClient注册转换器,我有点困惑 我使用的是框架和相应MongoClient的最新Micronaut版本 以下是我得到的供参考的例外情况: org.

我正在使用Micronaut和MongoDB创建一个新的应用程序。关于我的一些db对象,我不得不有点僵持

我有一个对象,其中包含一个枚举字段,我需要将其转换为可以保存的值(我计划将其作为字符串保存)

根据我的理解和收到的错误消息,我需要创建一个新的编解码器来处理这个问题(类似于JPA转换器)。虽然我已经找到了显示这一点的示例,但对于如何为MongoClient注册转换器,我有点困惑

我使用的是框架和相应MongoClient的最新Micronaut版本

以下是我得到的供参考的例外情况:

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class fts.marketing.models.CampaignEmailStatus.
    at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
    at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
    at com.mongodb.client.model.BuildersHelper.encodeValue(BuildersHelper.java:37)
    at com.mongodb.client.model.Filters$SimpleEncodingFilter.toBsonDocument(Filters.java:1109)
    at com.mongodb.client.model.Filters$AndFilter.toBsonDocument(Filters.java:946)
    at com.mongodb.internal.operation.Operations.createFindOperation(Operations.java:142)
    at com.mongodb.internal.operation.Operations.find(Operations.java:130)
    at com.mongodb.internal.operation.AsyncOperations.find(AsyncOperations.java:85)
    at com.mongodb.async.client.FindIterableImpl.createFindOperation(FindIterableImpl.java:229)
    at com.mongodb.async.client.FindIterableImpl.asAsyncReadOperation(FindIterableImpl.java:225)
    at com.mongodb.async.client.MongoIterableImpl.batchCursor(MongoIterableImpl.java:161)
    at com.mongodb.async.client.MongoIterableSubscription.requestInitialData(MongoIterableSubscription.java:46)
    at com.mongodb.async.client.AbstractSubscription.tryRequestInitialData(AbstractSubscription.java:151)
    at com.mongodb.async.client.AbstractSubscription.request(AbstractSubscription.java:84)
    at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1$1.request(ObservableToPublisher.java:50)
    at io.reactivex.internal.operators.flowable.FlowableToListSingle$ToListSubscriber.onSubscribe(FlowableToListSingle.java:84)
    at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1.onSubscribe(ObservableToPublisher.java:39)
    at com.mongodb.async.client.MongoIterableSubscription.<init>(MongoIterableSubscription.java:40)
    at com.mongodb.async.client.Observables$1.subscribe(Observables.java:47)
    at com.mongodb.reactivestreams.client.internal.ObservableToPublisher.subscribe(ObservableToPublisher.java:36)
    at com.mongodb.reactivestreams.client.internal.FindPublisherImpl.subscribe(FindPublisherImpl.java:189)
org.bson.codecs.configuration.CodecConfigurationException:找不到fts.marketing.models.CampaignEmailStatus类的编解码器。
位于org.bson.codecs.configuration.CodecCache.getorhrow(CodecCache.java:46)
位于org.bson.codecs.configuration.ProvidersCodeRegistry.get(ProvidersCodeRegistry.java:63)
位于org.bson.codecs.configuration.ProvidersCodeRegistry.get(ProvidersCodeRegistry.java:37)
位于com.mongodb.client.model.builderselper.encodeValue(builderselper.java:37)
位于com.mongodb.client.model.Filters$simplencodingfilter.toBsonDocument(Filters.java:1109)
位于com.mongodb.client.model.Filters$AndFilter.toBsonDocument(Filters.java:946)
位于com.mongodb.internal.operation.Operations.createFindOperation(Operations.java:142)
位于com.mongodb.internal.operation.Operations.find(Operations.java:130)
位于com.mongodb.internal.operation.AsyncOperations.find(AsyncOperations.java:85)
位于com.mongodb.async.client.finditerablempl.createFindOperation(finditerablempl.java:229)
位于com.mongodb.async.client.finditerablempl.asasasyncReadOperation(finditerablempl.java:225)
位于com.mongodb.async.client.mongoiterableempl.batchCursor(mongoiterableempl.java:161)
位于com.mongodb.async.client.MongoIterableSubscription.requestInitialData(MongoIterableSubscription.java:46)
位于com.mongodb.async.client.AbstractSubscription.tryrequestitalData(AbstractSubscription.java:151)
位于com.mongodb.async.client.AbstractSubscription.request(AbstractSubscription.java:84)
在com.mongodb.reactivestreams.client.internal.ObservabletPublisher$1$1.request(ObservabletPublisher.java:50)
在io.reactivex.internal.operators.flowable.FlowableToListSingle$ToListSubscriber.onSubscribe(FlowableToListSingle.java:84)
在com.mongodb.reactivestreams.client.internal.observetopublisher$1.onSubscribe上(observetopublisher.java:39)
位于com.mongodb.async.client.MongoIterableSubscription.(MongoIterableSubscription.java:40)
在com.mongodb.async.client.Observables$1.subscribe上(Observables.java:47)
位于com.mongodb.reactivestreams.client.internal.observetopublisher.subscribe(observetopublisher.java:36)
位于com.mongodb.reactivestreams.client.internal.FindPublisherImpl.subscribe(FindPublisherImpl.java:189)

我认为用编解码器创建一个类并使其可注入就足够了:

@Singleton
public class EnumCodec implements Codec<CampaignEmailStatus> {

  @Override
  public CampaignEmailStatus decode(BsonReader reader, DecoderContext decoderContext) {
    String enumString = reader.readString();
    return CampaignEmailStatus.valueOf(enumString);
  }

  @Override
  public void encode(BsonWriter writer, CampaignEmailStatus value, EncoderContext encoderContext) {
    String enumString = value.name();
    writer.writeString(enumString);
  }

  @Override
  public Class<CampaignEmailStatus> getEncoderClass() {
    return CampaignEmailStatus.class;
  }
}
如果它不工作,您应该能够从那里调试它


PS:我没有测试上面的代码,但它应该能让您了解

MongoDB java客户端在处理枚举方面不一致,而且仍然没有修复,请参阅

对于作为对象属性出现的枚举,有自动编解码器实现,它可以开箱即用。但是,如果将enum与
com.mongodb.client.model.Filters一起使用,它将不起作用,并最终导致问题中的异常

为Micronaut注册特定enum编解码器的解决方案是可行的,但它需要为要处理的每个enum定义一个编解码器bean。以下是适用于所有枚举的更通用的解决方案:

@Singleton
公共类EnumCodecRegistry实现CodecRegistry{
@抑制警告(“未选中”)
@凌驾
公共编解码器get(clazz类){
if(Enum.class.isAssignableFrom(clazz)){
返回新的EnumCodec(clazz);
}
返回null;
}
@凌驾
公共编解码器获取(类clazz,编解码器注册表){
返回获取(clazz);
}
私有静态类EnumCodec实现编解码器{
私人期末班;
EnumCodec(最后一节课){
this.clazz=clazz;
}
@凌驾
public void encode(最终BsonWriter writer、最终T值、最终EncoderContext EncoderContext){
writer.writeString(value.name());
}
@凌驾
公共类getEncoderClass(){
回击声;
}
@凌驾
公共T解码(最终BsonReader阅读器、最终DecoderContext DecoderContext){
返回Enum.valueOf(clazz,reader.readString());
}
}
}

非常感谢。你的建议很管用。我没想到做tbh会这么容易。遗憾的是,他们的文档中没有这样的例子。@Aris_Kortex很高兴它对你有用。Micronaut是一个开源框架。如果愿意,您可以随时提供进一步的文档。其他人将从你的学习中获益。
io.micronaut.configuration.mongo.reactive.DefaultReactiveMongoConfiguration#codecs