Reputation: 3350
I have a Spring Boot 2 project using MongoDB as database.
When I Instantiate an object containing a date as LocalDateTime by calling LocalDateTime.now(); I receive a datetime containing nanoseconds with more than 4 numerical places.
When I persist this data in mongoDB using mongotemplate.save, the value is saved containing 3 places for nanoseconds only (the rest is filled with zero). So, how can I accomplish the same precision when storing to DB? Or another option: how would I limit the precision when creating a LocalDateTime instance in java?
@Document("Entity")
public class Entity implements Serializable {
@Id
private String id;
@Indexed(name = "created")
private LocalDateTime created;
public HistoryEntity(){
// This gives me 2020-01-30T13:25:09.817182
this.created = LocalDateTime.now();
}
}
@Repository
public class DAO {
@Autowired
private MongoTemplate mongoTemplate;
public void save(Entity e) {
// When value is persisted, I get 2020-01-30T13:25:09.817 if I look into mongoDB instance or if I retrieve the same entity from DB in Java
Entity saved = mongoTemplate.save(e);
}
}
Upvotes: 2
Views: 3521
Reputation: 519
If the LocalDateTime
fields are only used for audit purposes (i.e. you don't need to query entities having a date/time field before/after a certain point in time)
you can store date/time as a String
, and deserialize the field back to your date/time object when retrieving the entity.
You can achieve this by registering custom converters in your mongo configuration. The following example is for Instant
because I'm using Instant
for audit fields rather than LocalDateTime
, but you can easily adapt it for your need.
@Configuration
public class MongoCustomConfig {
@Bean
MongoCustomConversions mongoCustomConversions() {
return new MongoCustomConversions(
List.of(instantStringConverter()));
}
@Bean
InstantStringConverter instantStringConverter() {
return new InstantStringConverter();
}
private static class InstantStringConverter implements Converter<Instant, String> {
@Override
public String convert(Instant source) {
return source.toString();
}
}
}
Upvotes: 0
Reputation: 3350
I think I found out the answer and probably there isn't much I can do other than truncate my LocalDateTime from java side (As I explained in my last comment and depicted below)
Clock millisecondClock = Clock.tick(Clock.systemDefaultZone(), Duration.ofNanos(1000000));
LocalDateTime d = LocalDateTime.now(millisecondClock);
I was reading this Baeldung's article https://www.baeldung.com/spring-data-mongodb-zoneddatetime when I faced the following statement (which answered my question):
... we're removing the nanoseconds information since the MongoDB Date type has a precision of milliseconds:
So that's it. Even if I want to work with a higher precision, seems that MongoDB can't handle it (at least for now)
Upvotes: 5