【问题标题】:YearMonth field stored on mongodb cannot be parsed back to object field存储在 mongodb 上的 YearMonth 字段无法解析回对象字段
【发布时间】:2016-06-15 01:40:38
【问题描述】:

背景:我的应用程序建立在 Spring Data RESTMongoDB Repositories 之上。

考虑这个带有YearMonth 字段的简单Java 域对象:

@Getter @Setter
public class Console {
    @Id private String id;
    private String name;
    private YearMonth releaseMonth;
    private Vendor vendor;
}

MongoRepository 实现使该域对象可用于持久性:

public interface ConsoleRepository extends MongoRepository<Console, String> {
    Console findByName(@Param("name") String name);
}

当公开一个 REST 控制器(由 Data REST 自动)来管理这个域对象时,我添加了 jackson-datatype-jsr310 gradle 依赖项,以便通过 jackson 将 YearMonth JSON 值(例如:“2016-04”)解析到这个字段中:

compile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1'

当 POST 到此端点时,JSON 文档中包含的 YearMonth 值被正确解析为 YearMonth 字段,并且整个对象成功存储为 MongoDB 上的文档。在 mongo 上查找此文档证明:

> db.console.find()
{ "_id" : ObjectId("575f837ca75df1fc7e5f4f96"),
  "_class" : "xxx.yyy.Console",
  "name" : "Console 1",
  "releaseMonth" : { "year" : 1988, "month" : 10 },
  "vendor" : "VENDOR_1" }

但是,当我尝试从 REST 控制器获取该资源时,MongoDB 客户端无法将此 YearMonth 值绑定到 Java 对象:

GET localhost:8080/consoles

回复:

{
  "timestamp": 1465954648903,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "org.springframework.data.mapping.model.MappingException",
  "message": "No property null found on entity class java.time.YearMonth to bind constructor parameter to!",
  "path": "/consoles"
}

我假设 MongoDB Java 客户端缺乏对 Java 8 的 YearMonth 值的内置支持,但由于它能够保存它们,这似乎被排除在外。我在这里想念什么?

【问题讨论】:

    标签: java spring mongodb mongodb-java


    【解决方案1】:

    我能够通过创建 Custom Converter 来解析这个对象:

    @Component
    public class DBObjectToYearMonthConverter implements Converter<DBObject, YearMonth> {
        @Override
        public YearMonth convert(DBObject source) {
            return YearMonth.of(
                (int) source.get("year"),
                (int) source.get("month")
            );
        }
    }
    

    并在 Application 类上设置 CustomConversions @Bean:

    @Bean
    public CustomConversions getCustomConversions() {
        return new CustomConversions(Arrays.asList(
            new DBObjectToYearMonthConverter()
        ));
    }
    

    欢迎使用其他选项。

    【讨论】:

    • 我尝试了同样的方法,但没有成功,所以我查看了日期并意识到我使用的是较新的版本,它是反应式的,我什至在使用 Kotlin。问题很简单,使用 DBObject 而不是 org.bson.Document。更正类型后,转换器工作。我只是想把它留在这里,以防有人更早制作这种转换器并想切换到新版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多