Backendless Support
 

Loading related data objects -the semi-lazy approach

There are several approaches to loading related data objects within Backendless Service Platform. Each of them has its peculiarities. For example, the approaches of loading object relations using theauto-load and the one-step approach return a complex hierarchy of data where the parent object includes child entities at the time when it is retrieved from the server.

Quite often these approaches are less than desirable for the reason that they may result in large payloads of data which may slow down data transfer and result in substandard user experience. Additionally, an entity stored in the Backendless backend may have a lot of related properties and it may be desirable to fetch a specific relation after the parent object has been loaded by the client. 

To enable loading of relations after the client retrieved the parent object, Backendless provides API to load related objects with a two-step approach. The "two-step" term describes the fact that the parent entity is loaded with the first call and the second call/step is to fetch specific relations. 

The sample code below demonstrates retrieval of the "locations" property for the Restaurant objects. This example is based on the Restaurant-to-Go application schema.

To master this feature it is important to follow the steps below to configure the Backendless backend with the schema and data for the application:

  1. Download the ZIP file which contains the definition for all tables from: https://backendless.com/documentation/samples/restaurant-app-schema.zip
  2. Login to console, select an app (it is recommended to create a new app for this) and click the Manage icon.
  3. Select the Import menu item.
  4. Click the single Zip file link located in the description text and browse to the ZIP file from step 1 above.

The restaurant table the sample works with looks as shown below:

NOTICE: the "Cantina Laredo" restaurant has related objects in the "locations" property. The code below retrieves a collection of the Restaurant objects (first step). Then the code makes a request to load the specific relation for each restaurant object:

 

JAVA

Asynchronous sample (Plain Java and Android):

private static void loadRelationsAsync() throws Throwable
{
 System.out.println( "\n============ Loading relations with the ASYNC API ============" );
 final CountDownLatch latch=new CountDownLatch( 1 );
 final AsyncCallback<Restaurant> loadRelationsCallback = new AsyncCallback<Restaurant>()
 {
 @Override
 public void handleResponse( Restaurant restaurant )
 {
 System.out.println( "\nRestaurant name = " + restaurant.getName() );
 printLocations( restaurant.getLocations() );
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 }
 };
 AsyncCallback<BackendlessCollection<Restaurant>> callback=new AsyncCallback<BackendlessCollection<Restaurant>>()
 {
 @Override
 public void handleResponse( BackendlessCollection<Restaurant> restaurants )
 {
 System.out.println( "Loaded " + restaurants.getCurrentPage().size() + " restaurant objects" );
 System.out.println( "Total restaurants in the Backendless storage - " + restaurants.getTotalObjects() );
 Iterator<Restaurant> iterator=restaurants.getCurrentPage().iterator();
 while( iterator.hasNext() )
 {
 Restaurant restaurant=iterator.next();
 List<String> relations = new ArrayList<String>();
 relations.add( "locations" );
 Backendless.Data.of( Restaurant.class ).loadRelations( restaurant, relations, loadRelationsCallback );
 }
 latch.countDown();
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 }
 };
 Backendless.Data.of( Restaurant.class ).find( callback );
 latch.await();
}
Synchronous sample (Plain Java):
private static void loadRelationsSync() throws Exception
{
 System.out.println( "\n============ Loading relations with the SYNC API ============" );
 BackendlessCollection<Restaurant> restaurants = Backendless.Data.of( Restaurant.class ).find();
 System.out.println( "Loaded " + restaurants.getCurrentPage().size() + " restaurant objects" );
 System.out.println( "Total restaurants in the Backendless storage - " + restaurants.getTotalObjects() );
 Iterator<Restaurant> iterator = restaurants.getCurrentPage().iterator();
 while (iterator.hasNext())
 {
 Restaurant restaurant = iterator.next();
 System.out.println( "\nRestaurant name = " + restaurant.getName() );
 List<String> relations = new ArrayList<String>();
 relations.add( "locations" );
 Backendless.Data.of( Restaurant.class ).loadRelations( restaurant, relations );
 printLocations( restaurant.getLocations() );
 }
}
The printLocations method used to print out the details of the related locations is:
private static void printLocations( List<Location> locations )
{
 if( locations == null )
 {
 System.out.println( "Restaurant locations have not been loaded" );
 }
 else if( locations.size() == 0 )
 {
 System.out.println( "There are no related locations" );
 }
 else
 {
 Iterator<Location> iterator = locations.iterator();
 while( iterator.hasNext() )
 {
 Location location = iterator.next();
 System.out.println( "Location: Street address - " + location.getStreetAddress() + ", City - " + location.getCity() );
 }
 }
}
The output produced by these methods:
============ Loading relations with the SYNC API ============
Loaded 4 restaurant objects
Total restaurants in the Backendless storage - 4
Restaurant name = McDonald's
There are no related locations
Restaurant name = Buca Di Bepo
There are no related locations
Restaurant name = Cantina Laredo
Location: Street address - 123 Main St., City - Frisco
Restaurant name = Endless Sweets
There are no related locations
============ Loading relations with the ASYNC API ============
Loaded 4 restaurant objects
Total restaurants in the Backendless storage - 4
Restaurant name = McDonald's
There are no related locations
Restaurant name = Endless Sweets
There are no related locations
Restaurant name = Buca Di Bepo
There are no related locations
Restaurant name = Cantina Laredo
Location: Street address - 123 Main St., City - Frisco

See the documentation for more information about loading relations with the two-step approach.

Review related topics:

Is article helpful?