spring-boot 2.1.0 mongo - CodecConfigurationException:找不到类 java.time.Year 的编解码器

Posted

技术标签:

【中文标题】spring-boot 2.1.0 mongo - CodecConfigurationException:找不到类 java.time.Year 的编解码器【英文标题】:spring-boot 2.1.0 mongo - CodecConfigurationException: Can't find a codec for class java.time.Year 【发布时间】:2019-04-19 01:16:31 【问题描述】:

我升级到 spring-boot 2.1.0.RELEASE 之后,当我尝试将文档保存到 mongodb 时,我得到了以下异常。

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.Year.

    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.ChildCodecRegistry.get(ChildCodecRegistry.java:51)
    at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:184)
    at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:199)
    at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:141)
    at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:387)
    at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:377)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:75)
    at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59)
    at com.mongodb.internal.connection.BsonWriterHelper.writePayloadArray(BsonWriterHelper.java:51)
    at com.mongodb.internal.connection.SplittablePayloadBsonWriter.writeEndDocument(SplittablePayloadBsonWriter.java:51)
    at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:118)
    at org.bson.codecs.BsonDocumentCodec.encode(BsonDocumentCodec.java:41)
    at com.mongodb.internal.connection.CommandMessage.addDocumentWithPayload(CommandMessage.java:179)
    at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:163)
    at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138)
    at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:57)
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:244)
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99)
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:444)
    at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72)
    at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:200)
    at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269)
    at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131)
    at com.mongodb.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:418)
    at com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:256)
    at com.mongodb.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:67)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:200)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:191)
    at com.mongodb.operation.OperationHelper.withReleasableConnection(OperationHelper.java:424)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:191)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:67)
    at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:193)
    at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:960)
    at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:494)
    at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:478)
    at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:472)
    at org.springframework.data.mongodb.core.MongoTemplate$6.doInCollection(MongoTemplate.java:1417)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:535)
    at org.springframework.data.mongodb.core.MongoTemplate.insertDocument(MongoTemplate.java:1410)
    at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:1217)
    at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:1150)
    at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:99)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy59.save(Unknown Source)
    at de.bindoc.mongoyeartest.FoobarRepositoryTest.save(FoobarRepositoryTest.kt:20)

这是文档:(在 kotlin 中)

data class Foobar(val id: ObjectId? = null, val year: Year, val name: String)

这是存储库:(在 kotlin 中)

interface FoobarRepository: MongoRepository<Foobar, ObjectId>

当我在FoobarRepository 上调用save 函数时,会触发异常。

我创建了一个 github 存储库来展示这种行为。

https://github.com/mheider/spring-boot-data-mongo-year-test

我必须注册自定义编解码器或转换器吗?

【问题讨论】:

请参考github.com/jhipster/generator-jhipster/issues/… 【参考方案1】:

答案是注册 MongoCustomConverters。 我刚刚添加了以下@Configuration 并且它起作用了。 (也更新了 github 仓库)

@Configuration
class MongoCustomConverterConfig() 
    @Bean
    fun mongoCustomConversions(): MongoCustomConversions =
        MongoCustomConversions(listOf(
            YearToIntConverter(),
            IntToYearConverter()
        ))


    @WritingConverter
    class YearToIntConverter: Converter<Year, Int> 
        override fun convert(p0: Year): Int? = p0.value
    

    @ReadingConverter
    class IntToYearConverter: Converter<Int, Year> 
        override fun convert(p0: Int): Year? = Year.of(p0)
    


【讨论】:

“转换器”在哪个包中?在 jackson、spring 和 bson 中有几个这样的类浮动 @LeeMeador Spring 的一员org.springframework.core.convert.converter.Converter;

以上是关于spring-boot 2.1.0 mongo - CodecConfigurationException:找不到类 java.time.Year 的编解码器的主要内容,如果未能解决你的问题,请参考以下文章

springboot集成mongo

使用 Spring 定义 Mongo 模式验证

spring-boot mongodb 4.0 兼容性

Spring-boot集成pgmongo多数据源

Spring-boot集成pgmongo多数据源

Springboot 容器使用 docker-compose 连接到 mongo 容器的 503 错误代码