Skip to content

Spring Data Commons does not support org.joda.DateTime in auditing [DATACMNS-1478] #1910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Feb 5, 2019 · 6 comments
Assignees
Labels
status: declined A suggestion or change that we don't feel we should currently apply type: bug A general bug

Comments

@spring-projects-issues
Copy link

abinet opened DATACMNS-1478 and commented

Hi all,

it seems that support of org.joda.DateTime is broken in latest Spring Data Commons. When I create a mongo entity with:

@CreatedDate
private org.joda.time.DateTime createdDate;

@LastModifiedDate
private org.joda.time.DateTime lastModifiedDate;

I get following error:

java.lang.IllegalArgumentException: Invalid date type class org.joda.time.DateTime for member 2019-02-05T09:29:54.709+01:00! Supported types are [org.joda.time.DateTime, org.joda.time.LocalDateTime, java.util.Date, java.lang.Long, long].java.lang.IllegalArgumentException: Invalid date type class org.joda.time.DateTime for member 2019-02-05T09:29:54.709+01:00! Supported types are [org.joda.time.DateTime, org.joda.time.LocalDateTime, java.util.Date, java.lang.Long, long]. at org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.rejectUnsupportedType(DefaultAuditableBeanWrapperFactory.java:252) at org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.access$000(DefaultAuditableBeanWrapperFactory.java:48) at org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory$DateConvertingAuditableBeanWrapper.lambda$null$3(DefaultAuditableBeanWrapperFactory.java:244) at java.util.Optional.orElseThrow(Optional.java:290) at org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory$DateConvertingAuditableBeanWrapper.lambda$getAsTemporalAccessor$4(DefaultAuditableBeanWrapperFactory.java:244) at java.util.Optional.map(Optional.java:215) at org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory$DateConvertingAuditableBeanWrapper.getAsTemporalAccessor(DefaultAuditableBeanWrapperFactory.java:234) at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.getLastModifiedDate(MappingAuditableBeanWrapperFactory.java:220) at org.springframework.data.rest.webmvc.HttpHeadersPreparer.lambda$getLastModifiedInMilliseconds$4(HttpHeadersPreparer.java:122)

It happens probably because org.springframework.data.convert.JodaTimeConverters does not have the converter from org.joda.time.DateTime <=> Instant but only org.joda.time.LocalDateTime <=> Instant although org.joda.time.DateTime still in org.springframework.data.auditing.AnnotationAuditingMetadata#SUPPORTED_DATE_TYPES.

Currently I can not find the way how to put my custom converter into conversionService to workaround this org.springframework.data.auditing.DefaultAuditableBeanWrapperFactory.DateConvertingAuditableBeanWrapper#DateConvertingAuditableBeanWrapper

Best regards
Andriy Binetsky

 


Affects: 2.1.4 (Lovelace SR4)

1 votes, 4 watchers

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

The support for Joda's DateTime has been a mistake in the first place as you cannot reliably keep the time zone defined in the DateTime within a legacy Date object as that always defaults to the system timezone. We really recommend to use either LocalDateTime (preferably Java 8's one) or Instant to represent time for persistence and then augment with user specific time zone for presentation purposes.

Jens Schauder can probably comment on the details

@spring-projects-issues
Copy link
Author

Jens Schauder commented

Conceptually: Use Instant.
It is the data type of denoting a point in time.
This is what the auditing is all about.
Anything with a time zone like DateTime is a going to result in the question: which time zone?
The one of the server, the client or the database?
And if you pick "server" this going to result in fun stuff when a cloud environment doesn't set the time zone to UTC on all servers.

Don't use LocalDateTime it isn't even a point in time.
Today 2am in New York and in Berlin are represented by exactly the same LocalDateTime instance. See http://blog.schauderhaft.de/2018/03/14/dont-use-localdatetime/ for more about that.

Leaving the puristic arguments aside: We do support various date-time related data types which aren't really fit for the job.

We could either remove support for those which will cause tons of issues and questions although it might make the world a better place.

Or we just (re(?))add org.joda.DateTime to the list.
Of course, there is the other issue that one might consider Joda obsolete with the arrival of the new time API in Java.

I actually think we should support Joda DateTime

@spring-projects-issues
Copy link
Author

jvanheesch commented

Any updates on this?
I'm currently unable to add spring-data-rest to an existing project, because the last-modified header support fails on this exact issue

@spring-projects-issues
Copy link
Author

abinet commented

jvanheesch you can workaround by configuring a MappingContext:

@Configuration
public class MongoDbConfig {

   @Bean
   public MongoMappingContext mongoMappingContext() {
      MongoMappingContext context = new MongoMappingContext();
      context.setSimpleTypeHolder(new SimpleTypeHolder(new HashSet<>(Arrays.asList(
            DateTime.class,
            LocalDateTime.class
      )), MongoSimpleTypes.HOLDER));
      return context;
   }
}

@spring-projects-issues
Copy link
Author

jvanheesch commented

Thank you abinet for adding your workaround - it'll definitely help others with the same problem!
I had the same error in a non-mongo context (spring-data-rest, Last-Modified header), and my workaround is as follows:

@Configuration
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
 public MyRepositoryRestMvcConfiguration(
  ApplicationContext context,
  @Qualifier("mvcConversionService") ObjectFactory < ConversionService > conversionService
 ) {
  super(context, conversionService);
 }

 @Bean
 public HttpHeadersPreparer httpHeadersPreparer() {
  return new HttpHeadersPreparer(auditableBeanWrapperFactory()) {
   @Override
   public HttpHeaders prepareHeaders(PersistentEntity < ? , ? > entity, Object value) {

    Assert.notNull(entity, "PersistentEntity must not be null!");
    Assert.notNull(value, "Entity value must not be null!");

    // Add ETag
    HttpHeaders headers = ETag.from(entity, value).addTo(new HttpHeaders());

    // Don't add Last-Modified, as this does not work with joda time!
    // getLastModifiedInMilliseconds(value).ifPresent(it -> headers.setLastModified(it));

    return headers;
   }
  };
 }
}

@spring-projects-issues spring-projects-issues added status: waiting-for-feedback We need additional information before we can continue type: bug A general bug labels Dec 30, 2020
@mp911de mp911de added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 30, 2020
@mp911de mp911de assigned mp911de and unassigned odrotbohm Jan 18, 2021
@mp911de
Copy link
Member

mp911de commented Jan 18, 2021

Meanwhile, we've deprecated Joda support and we're planning to remove support for Joda time entirely with Spring Data 3.0 (#2276). Therefore, we don't intend to address this issue anymore.

@mp911de mp911de closed this as completed Jan 18, 2021
@mp911de mp911de added status: declined A suggestion or change that we don't feel we should currently apply and removed status: feedback-provided Feedback has been provided labels Jan 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants