首页 > 解决方案 > SpringMongoDB persisting nested field with conversion produces org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for

问题描述

I have a class (Order) with a property(complexAction) whose type I use from another module/dependency. This I can't change and can't persist because of missing constructor. Now I try to replace this field for persistence with an own class, which can be persisted without problems, in a simple way using a customized Spring-MongoDB converter.

Unfortunately now I always get the error

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.example.issue_mongodb.intern.SimpleAction.

I found out that you can create the mapping context somehow by yourself and make this 'SimpleAction' entity known to MongoDB driver in it, but is there an easier way how to do this Spring-like?

Thx for the feedback :-)

@Data
@Builder
@Document
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    String id;
    //external api dependency, could not be updated
    ComplexAction complexAction;
}   

@Getter
public class ComplexAction {
    String actionName;
    LocalDateTime localDateTime;

    public ComplexAction(String actionName, Date time) {
        this.actionName = actionName;
        this.localDateTime = time.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

}

@Data
@Document
public class SimpleActionEntity {
    String name;
    Date time;
}


@WritingConverter
public class ComplexActionToSimpleActionConverter implements Converter<ComplexAction, SimpleActionEntity> {
    @Override
    public SimpleActionEntity convert(ComplexAction complexAction) {
        SimpleActionEntity simpleActionEntity = new SimpleActionEntity();
        simpleActionEntity.setName(complexAction.getActionName());
        LocalDateTime localDateTime = complexAction.getLocalDateTime();
        simpleActionEntity.setTime(
                Date.from(localDateTime.atZone(ZoneId.systemDefault())
                        .toInstant())
        );
        return simpleActionEntity;
    }
}


@ReadingConverter
public class SimpleActionToComplexActionConverter implements Converter<SimpleActionEntity, ComplexAction> {    
    @Override
    public ComplexAction convert(SimpleActionEntity simpleActionEntity) {
        return new ComplexAction(simpleActionEntity.getName(), simpleActionEntity.getTime());
    }
}


@Configuration
public class MongoDBConfig {
    @Bean
    public MongoCustomConversions mongoCustomConversions() {
        return new MongoCustomConversions(Arrays.asList(
                new SimpleActionToComplexActionConverter(),
                new ComplexActionToSimpleActionConverter()
        ));
    }
}

标签: type-conversionspring-data-mongodb

解决方案


推荐阅读