Skip to content

Saving New Objects

In order to determine if an object needs to be stored as new or the existing one should be updated, Backendless checks if the object in the API call has the objectId value. This principle is used in the save and update API as well as in the Deep Save API. Below are some of the examples demonstrating various scenarios:

Important

When using the Deep Save API to save new objects, make sure the tables are defined in the database. If the table does not have a column defined for a non-relational property in your object, the API will return an error.

Parent/Child Objects with one-to-one Relation

The sample below stores parent (Product) and child (Manufacturer) objects in the corresponding tables and creates a relationship between the objects in the database:

Map<String, Object> manufacturer = new HashMap<>();
manufacturer.put( "name", "Apple" );
manufacturer.put( "industry", "Consumer Electronics" );

Map<String, Object> product = new HashMap<>();
product.put( "name", "iPhone X");
product.put( "price", 1099 );
product.put( "manufacturer", manufacturer );

Backendless.Data.of( "Product" ).deepSave( product, new AsyncCallback<Map>()
{
    @Override
    public void handleResponse( Map savedObject )
    {
        Log.i( "MYAPP", "Product object has been saved " + savedObject.get( "objectId" ) );
    }

    @Override
    public void handleFault( BackendlessFault fault )
    {
        Log.i( "MYAPP", "Server reported an error " + fault.toString() );
    }
} );

Manufacturer manufacturer = new Manufacturer();
manufacturer.name = "Apple";
manufacturer.industry = "Consumer Electronics";

Product product = new Product();
product.name = "iPhone X";
product.price = 1099;
product.manufacturer = manufacturer;

Backendless.Data.of( Product.class ).deepSave( product, new AsyncCallback<Product>()
{
    @Override
    public void handleResponse( Product savedObject )
    {
        Log.i( "MYAPP", "Product object has been saved " + savedObject.objectId );
    }

    @Override
    public void handleFault( BackendlessFault fault )
    {
        Log.i( "MYAPP", "Server reported an error " + fault.toString() );
    }
} );
Manufacturer class. Public fields are used for brevity - JavaBean get/set methods are supported and recommended.
public class Manufacturer
{
  public String name;
  public String industry;
}
Product class. Public fields are used for brevity - JavaBean get/set methods are supported and recommended.
public class Product
{
  public String objectId;
  public String name;
  public double price;
  public Manufacturer manufacturer;
}

Once the code runs, the following two objects are stored in the Manufacturer and Product tables:

Object in the Manufacturer table:

manufacturer-obj

Object in the Product table:

product-obj

Parent/Child Objects with one-to-many Relation

In the example below the parent object (Order) contains two relations: one is a one-to-one relation to a Customer object and the other  is a collection (а one-to-many relation) of child objects (OrderItem). The Deep Save API stores the parent object, the children and establishes a relationship in the database between the parent and its children:

Map<String, Object> customer = new HashMap<>();
customer.put( "name", "John Smith" );
customer.put( "phoneNumber", "5551212" );

Map<String, Object> order = new HashMap<>();
order.put( "customer", customer );

Map<String, Object> apples = new HashMap<>();
apples.put( "name", "Apples" );
apples.put( "price", 5.99 );

Map<String, Object> oranges = new HashMap<>();
oranges.put( "name", "Oranges" );
oranges.put( "price", 9.99 );

ArrayList<Map<String, Object>> orderItems = new ArrayList<>();
orderItems.add( apples );
orderItems.add( oranges );

order.put( "orderItems", orderItems );

Backendless.Data.of( "Order" ).deepSave( order, new AsyncCallback<Map>()
{
    @Override
    public void handleResponse( Map savedObject )
    {
        Log.i( "MYAPP", "Order object has been saved " + savedObject.get( "objectId" ) );
    }

    @Override
    public void handleFault( BackendlessFault fault )
    {
        Log.i( "MYAPP", "Server reported an error " + fault.toString() );
    }
} );

Customer customer = new Customer();
customer.name = "John Smith";
customer.phoneNumber = "5551212";

Order order = new Order();
order.customer = customer;

OrderItem apples = new OrderItem();
apples.name = "Apples";
apples.price = 5.99;

OrderItem oranges = new OrderItem();
oranges.name = "Oranges";
oranges.price = 9.99;

order.addItem( apples );
order.addItem( oranges );

Backendless.Data.of( Order.class ).deepSave( order, new AsyncCallback<Order>()
{
    @Override
    public void handleResponse( Order savedObject )
    {
        Log.i( "MYAPP", "Order object has been saved " + savedObject.objectId );
    }

    @Override
    public void handleFault( BackendlessFault fault )
    {
        Log.i( "MYAPP", "Server reported an error " + fault.toString() );
    }
} );
OrderItem class. Public fields are used for brevity - JavaBean get/set methods are supported and recommended.
public class OrderItem
{
  public String name;
  public double price;
}
Customer class. Public fields are used for brevity - JavaBean get/set methods are supported and recommended.
public class Customer
{
  public String name;
  public String phoneNumber;
}
Order class. Public fields are used for brevity - JavaBean get/set methods are supported and recommended.
import java.util.ArrayList;

public class Order
{
  public String objectId;
  public Customer customer;
  public ArrayList<OrderItem> orderItems;

  public void addItem( OrderItem item )
  {
    if( orderItems == null )
      orderItems = new ArrayList<>();

    orderItems.add( item );
  }
}

When the Deep Save operation completes, the database will have the following objects:

Order object/table:

order-obj-deepsave

Customer object/table:

customer-obj-deepsave

OrderItem objects/table:

orderitem-obj-deepsave

Codeless Reference

data_api_deep_save_1

where:

Argument                Description
table name Name of the data table where a new record must be saved or updated.
object An object to save or update in the database. Object properties must match the names of the table columns.
return result Optional parameter. When this box is checked, the operation returns the saved or updated object with the objectId property.

The Deep Save API allows saving new objects or updating existing ones in the specified data table. You can easily save or update objects that have relations, this includes: parent objects and child objects.

Returns the saved object with the objectId property assigned by Backendless. This object has the other nested objects containing the related data.

Consider the structure of the data table called Customers. The "orders" column is configured to have one-to-many relations with objects stored in the Orders data table:

data_api_deep_save_2

The Orders data table contains the "items" column where the order details are stored in the JSON format.

data_api_deep_save_3

The example below saves a new object to the Customers data table. This object has two nested objects containing the related data that will be saved to the Orders data table, since initially the one-to-many relation was set in the Customers data table.

data_api_deep_save_4

After the Codeless logic runs, the new object gets saved to the Customers data table. As you can see, now the "orders" column is active and has relations to two other objects stored in the Orders data table.

data_api_deep_save_5

Two other objects stored in the Orders data table contain order information in the "items" column:

data_api_deep_save_6

The result of this operation will look as shown below after the Codeless logic runs:

data_api_deep_save_7