Realm Blog

Realm Java Reaches 4.0: Introducing ROS 2.0, Arrays of Primitives, and More!

We’re proud to introduce version 4.0.0 of Realm Java, which ships with many new features, improvements, and bug fixes. Read on to find out more about what we’ve added, improved, and deprecated — or head over to see what’s happening on Realm Cocoa or Realm .NET!

Realm Object Server 2.0 support

Now, you can take advantage of all the benefits of ROS 2.0, including improved scalability, better performance, packaging based on npm, and the powerful new Realm Studio development tool for inspecting and administering your synchronized Realms! Beginning with this release, if you are using synchronized Realms, Realm Java will now require Realm Object Server version 2.0 or later.

If you were previously running Realm Object Server 1.x and wish to upgrade to Realm Object Server 2.0, you should read our documentation, on how to properly handle migrations on the client!

Read more about Realm Object Server 2.0 here.

Arrays of primitives

You can now store primitive types or their nullable counterparts (more specifically: String, Integer, Boolean, Float, Double, Short, Long, Byte, byte[] and Date) directly within RealmLists. If you want to define a list of such primitive values you no longer need to define cumbersome single-field wrapper objects. Instead, you can just store the primitive values themselves!

Lists of primitive values work much the same way as lists containing objects, as the example below demonstrates.

public class Student extends RealmObject {
    public String name;
    public RealmList<Integer> testScores = new RealmList<>();
}

// Retrieve a student.
Realm realm = Realm.getDefaultInstance();
Student bob = realm.where(Student.class).equalTo("name", "Bob").findFirst();

// Give him a few test scores, and then print his average score.
realm.beginTransaction();
bob.testScores.deleteAllFromRealm();
bob.testScores.add(94);
bob.testScores.add(89);
bob.testScores.add(96);
realm.commitTransaction();

// in the future queries like the below will be supported 
bob.testScores.average()   // 93.0

Check out our documentation on many-to-many relationships for more information. Note that we don’t currently support querying lists of primitives, but plan to add this functionality in a future release.

Partial synchronization

We’re introducing an early version of Realm’s new Partial Synchronization feature. Though it’s still an experimental feature that we’re actively changing and improving, we think it’s an important new pattern that enables much more flexible architectures on Realm.

The Realm Object Server currently keeps synchronized Realms fully synchronized, meaning that all copies of the Realm (whether on the server or device) eventually converge towards containing the same data. While this is great for most use cases, especially if you want updates on one device to be transparently reflected everywhere else, sometimes you want more control over what objects are actually synchronized from the server onto a device.

For example, you might have a large read-only Realm representing a product catalog for a massive e-commerce website, and you might only want to sync to a user’s device those database entries representing some relevant subset of those products (perhaps something like “prosumer DSLR cameras made by Canon that are between $500 and $1000”).

Partial sync allows you to open a synced Realm in “partial synchronization mode.” Such a Realm won’t automatically download all information on the remote server, but will instead only sync down objects that match queries you make. Once those objects are synchronized, they behave like normal synced objects. They’ll update in real time based on remote changes, and any changes you make to those objects will be synced back up to the server.

Here is a toy example demonstrating what partial sync looks like in action:

// First, we specify that we want to open the Realm in partial synchronization mode (using `partialRealm()`)
SyncConfiguration syncConfig = new SyncConfiguration.Builder(user, url).partialRealm().build();
Realm partialSyncRealm = Realm.getInstance(syncConfig);

// Then we can subscribe to queries.
// Currently queries follow NSPredicate format, but this will change in the feature 
// as this feature is still in beta
String query = "price >= 500 AND price >= 1000 AND manufacturer == 'Canon' AND category == 'Cameras'"
partialSyncRealm.subscribeToObjects(Product.class, query, new Realm.PartialSyncCallback<Product>() {
    // Results are returned asynchronously.
    @Override
    public void onSuccess(RealmResults<Product> results) {
        Product firstCamera = results.first();
        System.out.println("The first product result: " + firstCamera.productName + " " + firstCamera.productDescription)");
    }

    @Override
    public void onError(RealmException error) {
        // An error occurred while fetching the results! 
    }
});

Check out our partial synchronization documentation for more details.

All permissions operations (retrieving permissions, applying or revoking permissions, creating or accepting permission offers) are now carried out declaratively via APIs on SyncUser.getPermissionManager(). The deprecated ROS 1.0 permissions system requiring permission and management Realms to be manually opened and inspected has been removed. See our documentation on access control for more information.

Also, Realm Object Server administrators who use the -retrieveInfoForUser:... API to retrieve information about a ROS user will now get metadata about the user stored on the server, as well as a list of all authentication provider accounts associated with that user.

API changes

A number of previously deprecated APIs have been removed. Our change log has a comprehensive table detailing what APIs have been removed or renamed, as well as what APIs should be used instead.


Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on the Realm Forums, Stack Overflow, GitHub, or Twitter.


Realm Java Team

The Realm Java Team is working around the clock (literally, we span 17 timezones) in order to create the best possible persistence solution on mobile. Easy-to-use, powerful features and first class performance is possible, and we are committed to building that.

Get more development news like this