web-dev-qa-db-ja.com

MongoDBでのZonedDateTime

ZonedDateTimeMongoDBとともに使用しようとしています。 ZonedDateTimeMongoDBに保存することはできますが、レコードを見ると、そこには不要なものがたくさんあります。

> "timestamp" : {
>             "dateTime" : ISODate("2016-12-13T13:45:53.991Z"),
>             "offset" : {
>                 "_id" : "-05:00",
>                 "totalSeconds" : -18000
>             },
>             "zone" : {
>                 "_class" : "Java.time.ZoneRegion",
>                 "_id" : "America/New_York",
>                 "rules" : {
>                     "standardTransitions" : [ 
>                         NumberLong(-2717650800)
>                     ],
>                     "standardOffsets" : [ 
>                         {
>                             "_id" : "-04:56:02",
>                             "totalSeconds" : -17762
>                         }, 
>                         {
>                             "_id" : "-05:00",
>                             "totalSeconds" : -18000
>                         }
>                     ],
>                     "savingsInstantTransitions" : [ 
>                         NumberLong(-2717650800), 
>                         NumberLong(-1633280400), 
>                         NumberLong(-1615140000), 
>                         NumberLong(-1601830800), 
>                         NumberLong(-1583690400), 
>                         NumberLong(-1570381200),
> and so on....

また、同じ日付を取得しようとすると、次のようになります。

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

LocalDateTimeを使用する場合、この問題はありませんでした。最初の質問は、ISODateZonedDateTimeでのみ持続する設定をどこかに変更できるかどうかです。 2つ目の質問は、Jsr310JpaConverters for mongodb

UPDATE:次の質問表を参照して、カスタムコンバーターを作成して登録しましたが、問題は解決しません。 Spring Data MongoDB with Java 8 LocalDate MappingException

public class ZonedDateTimeToLocalDateTimeConverter implements Converter<ZonedDateTime, LocalDateTime> {
    @Override
    public LocalDateTime convert(ZonedDateTime source) {
        return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId
                .systemDefault());
    }
}

そして

public class LocalDateTimeToZonedDateTimeConverter implements Converter<LocalDateTime,
        ZonedDateTime> {
    @Override
    public ZonedDateTime convert(LocalDateTime source) {
        return source == null ? null : ZonedDateTime.of(source, ZoneId.systemDefault());
    }
}

次のように登録しました。

@Bean
public CustomConversions customConversions(){
        List<Converter<?,?>> converters = new ArrayList<Converter<?,?>>();
        converters.add(new ZonedDateTimeToLocalDateTimeConverter());
        converters.add(new LocalDateTimeToZonedDateTimeConverter());
        return new CustomConversions(converters);
    }

@Bean
public MongoTemplate getMongoTemplate() throws UnknownHostException {
        MappingMongoConverter converter = new MappingMongoConverter(
                new DefaultDbRefResolver(getMongoDbFactory()), new MongoMappingContext());
        converter.setCustomConversions(customConversions());
        converter.afterPropertiesSet();
        return new MongoTemplate(getMongoDbFactory(), converter);
    }
11
Gurkha

SpringはすべてのJava時間コンバーターからゾーン化された日付時刻コンバーターを差し引いたもの)をサポートしているようです。次のように登録できます。

@Bean
public CustomConversions customConversions(){
    List<Converter<?,?>> converters = new ArrayList<Converter<?,?>>();
    converters.add(new DateToZonedDateTimeConverter());
    converters.add(new ZonedDateTimeToDateConverter());
    return new CustomConversions(converters);
}

@Bean
public MongoTemplate getMongoTemplate() throws UnknownHostException {
    MappingMongoConverter converter = new MappingMongoConverter(
            new DefaultDbRefResolver(getMongoDbFactory()), new MongoMappingContext());
    converter.setCustomConversions(customConversions());
    converter.afterPropertiesSet();
    return new MongoTemplate(getMongoDbFactory(), converter);
}

class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {

     @Override
     public ZonedDateTime convert(Date source) {
              return source == null ? null : ofInstant(source.toInstant(), systemDefault());
         }
     }

class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {

    @Override
    public Date convert(ZonedDateTime source) {
             return source == null ? null : Date.from(source.toInstant());
       }
   }

他のもう1つの解決策は、ZonedDateTimeを使用し、MongoDBに永続化しながら日付に変更することです。フェッチ中に日付からゾーン日付時刻に簡単に戻すことができます。

以下は、変換に役立つ関連メソッドです。

ZoneId zoneID = ZoneId.of("America/Chicago");

ZonedDateTimeからJava util date。

Instant instant = Instant.now();
ZonedDateTime zonedDateTime = instant.atZone(zoneId);
Date date = Date.from(zdt.toInstant());

日付からZonedDateTimeへ

Instant instant = date.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(zoneId);

もう1つの方法は、変換に役立つカスタムコーデックを実装することです。 MongoドキュメントからFiltering YearMonthでYearMonth用に1つ作成しました。ゾーン化された日付時刻のカスタムコーデックを作成する場合は、演習として残しておきます。

以下のライブラリをコーデックベースのアプローチに使用できます。

https://github.com/ylemoigne/mongo-jackson-codec

13
user2683814

これをデバッグするのにあまりにも多くの時間を費やした後、私はついに最新バージョンの春のブーツ/春のデータのための実用的な解決策を見つけました。これは現在、Spring Boot 2.0.0.M7で動作しています。

Veeramからの受け入れられた回答で、私はCouldn't find PersistentEntity for type

これが誰かがうさぎの穴を下らないようにするのに役立つことを願っています。

@Configuration
public class MongoConfiguration {

    @Bean
    public MongoCustomConversions customConversions(){
        List<Converter<?,?>> converters = new ArrayList<>();
        converters.add(DateToZonedDateTimeConverter.INSTANCE);
        converters.add( ZonedDateTimeToDateConverter.INSTANCE);
        return new MongoCustomConversions(converters);
    }

    enum DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {

        INSTANCE;

        @Override
        public ZonedDateTime convert(Date source) {
            return ofInstant(source.toInstant(), systemDefault());
        }
    }

    enum ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {

        INSTANCE;

        @Override
        public Date convert(ZonedDateTime source) {
            return Date.from(source.toInstant());
        }
    }
}
7
Alex Spence