realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.46k stars 1.75k forks source link

Realm java, entity set date throws error Date/timestamp is outside valid range #1277

Closed holyman2k closed 9 years ago

holyman2k commented 9 years ago

Hi i'm writing an andorid app using Realm. I'm downloading some json data containing a list of project from our server and save the result to Realm, but i'm been encountering a bug with

 java.lang.IllegalArgumentException: Date/timestamp is outside valid range
      at io.realm.internal.UncheckedRow.setDate(UncheckedRow.java:201)
      at io.realm.ProjectRealmProxy.setExpiry(ProjectRealmProxy.java:92)
      at io.realm.ProjectRealmProxy.copy(ProjectRealmProxy.java:238)
      at io.realm.ProjectRealmProxy.copyOrUpdate(ProjectRealmProxy.java:229)
      at io.realm.DefaultRealmModuleMediator.copyOrUpdate(DefaultRealmModuleMediator.java:123)
      at io.realm.Realm.copyOrUpdate(Realm.java:1565)
     at io.realm.Realm.copyToRealm(Realm.java:1116)

The issue occurs when i'm try to save a project with a expiry date of 2040-11-30. The data from json is in string format, I convert to date with a SimpleDateFormatter. Is this a bug or I'm doing something wrong?

beeender commented 9 years ago

Same question on stackoverflow http://stackoverflow.com/questions/31307150/realm-java-date-timestamp-is-outside-valid-range

There is a limitation of Date in Realm-java right now, see https://realm.io/docs/java/latest/#general

The dates are truncated with a precision of one second. In order to maintain compatibility between 32 bits and 64 bits devices, it is not possible to store dates before 1900-12-13 and after 2038-01-19.

Same issue with #833

@holyman2k Thanks a lot for your feedback! For easier issue tracking, I am closing this issue now. If you have any further comments, feel free to post them on #833 .

yolapop commented 9 years ago

Hi, I got strange error. What's strange is I never have a date string that's beyond 2018. Plus, it happens randomly on various Date field, for example I have a User class that has created_at, updated_at, since... I discovered first error was at since and then next error was at updated_at field.

cmelchior commented 9 years ago

Can you provide an example of a date that fails?

yolapop commented 9 years ago

@cmelchior the date is from network and parsed from string format like 2015-07-10T11:00:00.000Z. How can I log the value that fails?

cmelchior commented 9 years ago

Below should work, at least if you only copy a single object.

try {
 realm.copyToRealm(obj);
} catch (IllegalArgumentException e) {
  Log.i(TAG, obj.getDate())
}
yolapop commented 9 years ago

I have a list of objects :(

cmelchior commented 9 years ago

Try splitting it up before copying. It will be slower, be just for testing it would be OK:

for (Foo obj : objects) {
  try {
   realm.copyToRealm(obj);
  } catch (IllegalArgumentException e) {
    Log.i(TAG, obj.getDate())
  }
}
yolapop commented 9 years ago

So this is the code

for (Doctor doctor : doctors) {
    try {
        realm.copyToRealmOrUpdate(doctor);
    } catch (IllegalArgumentException e) {
        Log.i("realmdate", "since: " + String.valueOf(doctor.getSince()));
        Log.i("realmdate", "until: " + String.valueOf(doctor.getUntil()));
        Log.i("realmdate", "createdAt: " + String.valueOf(doctor.getCreatedAt()));
        Log.i("realmdate", "updatedAt: " + String.valueOf(doctor.getUpdatedAt()));
    }
}

And the log

07-30 15:23:21.161  19359-21023/com.myapp I/realmdate﹕ since: Mon Jul 10 11:00:00 GMT+07:00 2015
07-30 15:23:21.161  19359-21023/com.myapp I/realmdate﹕ until: Sun Jul 10 11:00:00 GMT+07:00 2016
07-30 15:23:21.161  19359-21023/com.myapp I/realmdate﹕ createdAt: Sat Jul 11 14:53:45 GMT+07:00 2015
07-30 15:23:21.161  19359-21023/com.myapp I/realmdate﹕ updatedAt: Thu Jul 23 11:06:05 GMT+07:00 2015

Looks like a fine date, right? The write is in background thread, if it helps

yolapop commented 9 years ago

For the past half an hour I've been restarting the app a few times and clicking a button that refreshes the data. I've only got 1 error since then and it happened at different object, different date. It was completely random, maybe it's a concurrency problem? The refresh button also clears previous data (clear the Doctor.class from realm).

yolapop commented 9 years ago

Update: I have not been able to reproduce the error after the change in my code

So the flow before:

  1. Click a button
  2. Clear Doctor.class from realm result (realm on UI thread)
  3. Cancel all running thread
  4. Make new thread to fetch the data and update the doctors list (realm on background thread)

I changed it to this and haven't found an error since:

  1. Click a button
  2. Cancel all running thread
  3. Clear Doctor.class from realm result (realm on UI thread)
  4. Make new thread to fetch the data and update the doctors list (realm on background thread)
cmelchior commented 9 years ago

That does sounds a bit odd. RealmObjects should be thread safe, so it sounds maybe like you are parsing your original objects around and that something happens to them.

Eg.

Doctors doctors = getDoctors();
List<Doctor> realmDoctors = realm.copyToRealm(doctors);

doStuff(doctors); // These doctors are not thread safe and not persisted in Realm. These should no longer be used.
doStuff(realmDoctors); // These doctors are the one you want.
yolapop commented 9 years ago

Thanks, I'll look again maybe I missed something

emanuelez commented 9 years ago

Please let us know how it goes! :)

yolapop commented 9 years ago

Hi yeah, sorry. I know it's weird, before this, I use the ordinary Thread for background processing, then I remembered, I should use AsyncTask, duh. And then I never see the error again. So it must be my fault. Thanks :)