当前位置: 首页 > 知识库问答 >
问题:

Spring MongoDB-无法为java.time.期间编写自定义转换器

酆鸿哲
2023-03-14

我使用的是Spring云Brixton。SR4带有Spring数据MongoDB。

我有一个非常简单的实体:

@Document
public class Foo{
    private Period period;

    //getter & setter
}

因为java。时间jsr310不支持句点,我正在创建自定义转换器:

class Converters {
    @Component
    @WritingConverter
    static class PeriodToStringConverter implements Converter<Period, String> {
        @Override
        public String convert(Period period) {
            return period.toString();
        }
    }

    @ReadingConverter
    @Component
    static class StringToPeriodConverter implements Converter<String, Period> {

        @Override
        public Period convert(String s) {
            return Period.parse(s);
        }
    }

现在,我在我的配置类extending中注册它们,AbstractMongoConfiguration:

    @Bean
    @Override
    public MappingMongoConverter mappingMongoConverter() throws Exception {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
        final CustomConversions conversions = customConversions();
        log.info("hasCustomWriteTarget(Period.class): " + conversions.hasCustomWriteTarget(Period.class));
        log.info("hasCustomWriteTarget(Period.class, String.class): " + conversions.hasCustomWriteTarget(Period.class, String.class));
        log.info("hasCustomReadTarget(String.class, Period.class): " + conversions.hasCustomReadTarget(String.class, Period.class));
        converter.setCustomConversions(conversions);
        converter.afterPropertiesSet(); //probably not needed, trying out of despair
        return converter;
    }

    @Bean
    @Override
    public CustomConversions customConversions() {
        List<Converter> converters = new ArrayList<>();
        converters.add(new Converters.PeriodToStringConverter());
        converters.add(new Converters.StringToPeriodConverter());
        return new CustomConversions(converters);
    }

当我启动我的应用程序时,我在日志中看到:

hasCustomWriteTarget(Period.class): true
hasCustomWriteTarget(Period.class, String.class): true
hasCustomReadTarget(String.class, Period.class): true

现在,我创建一个新的Foo并将其保存到我的存储库中:

Foo foo = new Foo();
foo.setPeriod(Period.of(2, 0, 1));
fooRepository.save(foo);

现在奇怪的事情发生了:

在Mongodb中,我看到:

{
  "_id": ObjectId("xxxx"),
  "period": {
      "years" : 0,
      "months" : 2,
      "days" : 1
    }
}

所以这已经有问题了。应将其保存为字符串

当我尝试用Java读取对象时,我得到:

org.springframework.data.mapping.model.MappingException: No property null found on entity class java.time.Period to bind constructor parameter to!

我调试了MappingMongoConverter中的代码:

    if (conversions.hasCustomReadTarget(dbo.getClass(), rawType)) {
        return conversionService.convert(dbo, rawType);
    }

因为我的对象没有存储为字符串,所以dbo变量实际上是一个基本的对象,因此我没有用于此的转换器。

你知道为什么我的写转换器没有被用来保存周期吗?

我的类路径上有jackson-datatype-jdk8,这可能是问题所在吗?杰克逊会因为坚持使用Mongodb而卷入其中吗?

编辑

这似乎是一个注册问题。调试代码时,MappingMongoConverter中使用的自定义转换对象与我创建的对象不同。它没有我创建的自定义转换器

共有1个答案

韩夕
2023-03-14

好吧,这太愚蠢了。。。

我还创建了自己的MongoTemboard

@Bean
public MongoTemplate mongoTemplate() throws Exception {
    return new MongoTemplate(mongoDbFactory());
}

这基本上忽略了我的自定义转换器。要修复它:

@Bean
public MongoTemplate mongoTemplate() throws Exception {
    return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
}
 类似资料:
  • 我为jsf创建了一个自定义转换器。getAsObject()工作正常,但getAsString()返回异常。我不确定问题出在哪里,我尝试过用不同的方式将对象转换为字符串,但它不断返回异常。 这是我的代码: 这是Product类(为简单起见排除了getter/Setters/equals()/hash()): 这是stack我得到的: 这是我使用转换器的jsf:

  • 我正在尝试替换org.joda。现在是java时代。时间在我们的应用程序中。从那时起,我们使用的是org.joda。在时间包中,我们有一个带有org.joda.time.period的ISO8601格式的period。 由于P1Y、P1M、P1W、P1D等格式已存储在我们的系统中,因此在java.time.中寻找相同内容的格式化程序 java.time.Duration支持,小时,分钟和天。 但是

  • 我正在使用mvn依赖项google-cloud d-dataflow-java-sdk-all版本2.1.0,我正在尝试为我的管道添加一个自定义Sink。 在管道中,我正在检索Pubsub消息,并最终将这些消息转换为PCollection of Strings。 这是我设置的管道的简化版本: 我需要自定义Sink的原因是因为团队中的其他人已经编写了将这些数据写入BigQuery的代码,并为此提供了

  • 我在应用程序中使用C#对象持久性模型,并从外部源填充表。我插入带有以下日期的行(在String列中):。这是使用以下Go代码从时间戳生成的: 但是,DynamoDB对象持久性模型在尝试将其转换为时会窒息,并出现以下错误: 如果我让我的服务编写一个系统。DateTime(使用包含DateTime属性的POCO),它看起来像这样:

  • 主要内容:JSF自定义转换器实例我们可以在JSF中创建自己的自定义转换器。 以下列表是我们可以在JSF中创建自定义转换器的步骤。 通过实现接口创建一个转换器类。 实现上述接口的和方法。 使用注解为自定义转换器分配唯一的ID。 JSF自定义转换器实例 打开 NetBeans IDE 创建一个Web工程:CustomConverter,其目录结构如下所示 - 创建以下文件代码,文件:index.xhtml 的代码内容如下所示 - 文

  • I'v开始寻找很好的解决方案,如何使用Spring CassandraOperations很好地持久化实体。问题的出现是因为我的实体中的某些字段不支持cassandra,例如joda DateTime。 解决方法是在java类型的同一实体中有其他字段。util。Date而不是joda DateTime,用@Transient标记未要求的字段。但这并不干净,所以我开始寻找自动自定义转换。 目前,sp