I'm currently running Realm Version 0.82.0 in one of my Android projects. I didn't touch Realm for quite some time, until I recently noticed that they went up until version 2.0.2 in the meantime. I would like to upgrade my version of Realm, unfortunately, I don't know if the upgrade from my old version to the current release will be working or breaking my code.
I'm especially concerned of migrations, since the API for migrations seemed to have changed a bit since my code, and I'm unsure if my migrations will break if I just update my version. Unfortunately, there is no documentation about upgrading Realm version available on their webpage.
Does anyone have any experience with upgrading Realm, especiall a version increase over two major versions?
The main upgrade to Realm from
4+
to5+
needs to change from:To:
The list of breaking changes is available in the CHANGELOG.MD on their Github.
However, it's worth noting that there were quite a few breaking changes on the road, especially noting 0.89.0.
From
0.82.0
to5.1.0
is the following (which is the most stable version at the moment):0.82.0:
(0.82.2 was most stable here, but it didn't work on Blackberry devices. The first stable version to use on Blackberry was 0.87.2.)
In 0.86.0+, you can add an index to the annotated field using
0.83:
Oh boy, this is a nice one. NULL support.
Boxed types for primitives became available. Boxed types are nullable by default. All
String
,Date
, andbyte[]
must be annotated with@Required
, orschema.setNullable("fieldName", nullability)
and make them all nullable.0.84.0:
Async queries were added. Nothing new here in terms of schema.
0.85.0:
Nothing important here yet, although:
This one is an interesting one. Previously it just failed, so this is for the best. But it is Realm's largest limitation, too.
0.86.0:
The new Migration API, using
DynamicRealm
instead ofRealm.getTable()
.Some stuff were renamed, and you ought to unregister your change listeners if your result set is still valid. But it's worth noting that you should still retain a field variable to your
RealmResults
, because Realm'sContext
only has a weak reference to it.0.87.0:
RX support. Nothing important.
0.87.2:
Finally, Realm got stable again! :)
0.88.0:
Welp. It's an AAR now. You have to add to
classpath
and run it withapply plugin: 'realm-android'
instead ofcompile ...
dependency.Change listeners are only called on the next event loop, instead of immediately after commit. I'm.. honestly not entirely sure of the ramifications of this, but it means change listeners don't work on background threads. Only on looper threads (primarily the UI thread).
This is quite necessary though, so I wouldn't want to get stuck on 0.87.5 for sure.
0.89.0:
Okay, this one is the most messy one.
1.) you must add
@Required
annotation for@PrimaryKey
annotated fields, becausenull
is a valid primary key value.2.)
realm.refresh()
no longer works. It will be removed anyways. Here's a workaround for 1.1.1 though, should be used only on background threads. It is available in Realm 3.2 again, though.3.)
getTable()
is removed. Don't use it. Use the new migration API.4.)
realmResults.sort()
returns a new RealmResults, which needs to have the change listener appended to it as well. I think it's unreliable, so I'd just usefindAllSorted()
instead.5.) You might not think much of it, but
This literally meant that
RealmResults
were only updated when the event loop occured, it was NOT immediately updated when you callrealm.commitTransaction()
. This also means that on background threads, the RealmResults did NOT update when youcommitTransaction()
, you had to requery them.The
RealmResults
are only known to be updated after the appendedRealmChangeListener
is called. In 1.1.1, when theRealmChangeListener
is called, all Results had been updated.This change however also changed iteration behavior in transactions. In transactions, you always saw the newest version. This meant that a query was re-evaluated as you were iterating on it, and modifying elements. (THIS IS ALSO THE CASE SINCE REALM 3.0)
Example, previously this was valid code:
However, this will no longer work. For me, this caused issues because I iterated sometimes like this
This is a problem, because the
stuffs
will no longer change. I had to do a search for--
in my code and fix all iteration like this.The official workaround used to be this:
This would still work fine in 0.89.0.
Since 0.89.0, this is valid code too (and in 3.0.0+, this automatically creates a snapshot collection):
The elements in the results still get invalidated though, but the results themselves don't change. (This is the same for snapshot collections as well in Realm 3.0.0+).
0.90.0:
So
RealmBaseAdapter
is now inrealm-android-adapters
, for1.1.1
of Realm, use1.3.0
. Also addsRealmRecyclerViewAdapter
. For3.5.0
, use2.0.0
or newer.RealmChangeListeners got an
element
parameter. Yay.Also, Date now has
milisecond
precision.0.91.0:
Deprecated a lot of methods in 0.90.0, so
waitForChange()
doesn't really work as people would intend to use it, so here's a workaround for 1.1.1 to 3.1.4 though, should be used only on background threads.refresh()
will be re-added in 3.2.0.Also, at some point
Realm.getInstance(Context)
was removed, useRealm.getInstance(new RealmConfiguration.Builder(Context).build())
instead.After that, 1.0.0 came, so it's pretty much just that.
By the way, in 1.1.0,
insertOrUpdate()
was added which is faster thancopyToRealmOrUpdate()
, and doesn't return a proxy.2.0.2:
Primary keys are immutable on managed objects, once it's set, it cannot be changed, and it throws an exception if you try. Also, use
realm.createObject(clazz, primaryKeyValue)
if you usecreateObject()
to create objects.You must call
Realm.init(Context)
at some point.Configuration Builder no longer receives Context.
armeabi
is no longer supported. (only v7a and the others)No breaking changes until 3.0.0, but a ton of bugfixes.
3.0.0:
Due to the Realm ObjectStore Results integration,
RealmResults
is live again in transactions, just like back in 0.88.3 and before.So
simple for loops
(indexing withfor(int i = 0; ...
) is prone to break - meaning you either need to reverse iterate them, or create a snapshot collection first.Also,
RealmObject
change listener will now also emit on deletion, you need to check forisValid()
in the change listener. This is so that you can update the UI if the object has been deleted in the background.3.1.0:
Nothing to do here, but it's worth a mention.
3.2.0-3.2.1:
Nothing to do here, except update proguard, because there was a bug introduced here. Added proguard section.
3.3.0: (and 3.3.1)
Nothing to do here, the bug was fixed which caused the Proguard problem in 3.2.0.
3.4.0:
Nothing to do here, although it's worth looking at the new
@LinkingObjects
API for inverse relationships.In fact, it is recommended to replace bi-directional links with uni-directional link + inverse relationship.
3.5.0:
If you haven't specified all RealmObjects in the
modules()
(in case you use multiple modules instead of just the default, for example RealmObjects from a library project), then you need to make sure you actually provide all RealmObjects that are part of the schema in your modules.Previously it silently added them even if they were not in the modules, now that is not the case.
4.0.0:
So Rx1 support was replaced with Rx2 support, and
removeChangeListeners()
was renamed toremoveAllChangeListeners()
.Most other things only affect sync Realms, and from this point it is possible to use
RealmList<String>
,RealmList<Date>
, andRealmList<Integer>
as part of the Realm schema. Querying them is not yet supported, and they are not filled out bycreate*FromJson
methods.4.3.1:
Instead of using
realm.where(Blah.class).distinct("something")
orrealm.where(Blah.class).findAllSorted("something")
, you can now do5.0.0:
So this means that
realm.where(...).findAllSorted("field")
should berealm.where(...).sort("field").findAll()
.Also comes that
OrderedRealmCollectionChangeListener
used to sendnull
as the initial change set, now that is no longer the case, and== null
should be replaced with.getState() == OrderedCollectionChangeSet.State.INITIAL
. This also means that you need to userealm-android-adapters 3.0.0
or newer with Realm 5.0+.Also, if you relied on the names of
__RealmProxy
classes: they are named by their fully qualified name, including packages, likemy_package_SomeObjectRealmProxy
.PROGUARD RULES