Simple Data Operations sample (Java)

The Simple Data Operations console sample demonstrates the most basic & common interactions you will make to an instance of Relativity Server. It shows how to:

  • connect to the server
  • retrieve a table from the server
  • add a row to the retrieved table and apply that change to the server
  • update/change the contents of a row and apply that change to the server
  • delete a row from the table and apply that change to the server

Getting Started

The Simple Data Operations sample is installed in C:\Users\Public\Documents\RemObjects Samples\Data Abstract for Java\Java\Console\.

To build it you can either build & execute it from the command line or make use of the provided Eclipse .classpath and .project files.:

If using the command line remember that you will need to explicitly include the two jar files provided by the Data Abstract for Java package in the classpath. So for example to build and run this sample you'll need:

  • Build: javac -cp "C:/Program Files/RemObjects Software/Data Abstract for Java/Bin/com.remobjects.dataabstract.jar";"C:/Program Files/RemObjects Software/Data Abstract for Java/Bin/com.remobjects.sdk.jar";src src\com\remobjects\dataabstract\samples\simpledataoperations\Program.java
  • Execute: java -cp "C:/Program Files/RemObjects Software/Data Abstract for Java/Bin/com.remobjects.dataabstract.jar";"C:/Program Files/RemObjects Software/Data Abstract for Java/Bin/com.remobjects.sdk.jar";src com.remobjects.dataabstract.samples.simpledataoperations.Program

Like all the samples provided with Data Abstract for Java you will need to be running the Relativity Server with the DASamples Domain and the Simple Schema available.

Lastly this sample makes use of a convenience class (DataTableExtension) which is provided with Data Abstract for Java. It provides a single public method LogToString that takes a DataTable and converts its contents into a String in a pretty fashion that could be logged to a console or into a file. Please note that this class extension is intended for test purposes only.

Running the Sample

When run the sample sets up a connection to an instance of Relativity Server and logs in (Step 1). It then retrieves only the "DepId", "DepName" and "DepPhone" fields from the "Deps" table and prints the table to the console (Step 2). It then inserts a new row with a department name ("DepName") of "Security" and phone number ("DepPhone") of "(873)000-00-00" before applying those changes to the original on the server (Step 3). The phone number is then updated to a new value (Step 4) before the new row is deleted from the table (Step 5).

Examining the Code

All of the code can be found in the Program.java source file.

The Deps schema table used here has three fields:

  • DepId is the primary key and use an AutoInc data type.
  • DepName is a string of up to 50 characters and is required for each new row
  • DepPhone is also a string of up to 50 characters, the field is optional.

Setting up a Connection & Logging in (Step 1)

There are three stages to setting up a connection to an instance of Relativity Server.

In the first stage we initialize the underlying services that we will use to establish the connection to the server. The BinMessage is a message type that will be used to encode the data as a message. The HttpClientChannel is the communications channel over which the data will be sent, here we are establishing that it uses "HTTP" and specifying the address of the server. Finally an instance of Bin2DataStreamer is created which will handle the encoding and decoding of the data packets being transmitted.

The second stage is to configure a RemoteDataAdapter object that we interact with to communicate with the server. After its created you pass it the three objects we created previously and set the DataServiceName and LoginServiceName. At this point we have a working connection but we will be unable to manipulate the schema data until we log in. Attempting to do so will cause an ROException exception to be thrown with the message "Session could not be found.".

The final stage passes a special login string (lLoginString) to the login method to establish a login session. The login method returns a boolean which will be true if the login attempt was successful or false if it failed. The login string is comprised of 4 parts:

  • Username the username to attempt to login with
  • Password the password to use
  • Domain the name of the domain that the schema is located in
  • Schema the name of the schema we wish to use

For example, the login string from this sample is "User Id=simple;Password=simple;Domain=DASamples;Schema=Simple"

NOTE If there is a problem attempting to communicate with the server, or if the schema or domain name is incorrect then an ROException will be thrown and should be handled appropriately.

BinMessage lMessage = new BinMessage();
HttpClientChannel lChannel = new HttpClientChannel();
try {
    lChannel.setTargetUrl(new URI("http://localhost:7099/bin"));
} catch (URISyntaxException e1) {
    e1.printStackTrace();
}

System.out.println(String.format("Target URL is %s", lChannel
        .getTargetUrl().toString()));
System.out.println("RO SDK layer is configured.");

Bin2DataStreamer lDataStreamer = new Bin2DataStreamer();
RemoteDataAdapter lDataAdapter = new RemoteDataAdapter();
lDataAdapter.setDataStreamer(lDataStreamer);
lDataAdapter.setMessage(lMessage);
lDataAdapter.setClientChannel(lChannel);
lDataAdapter.setDataServiceName("DataService");
lDataAdapter.setLoginServiceName("LoginService");

System.out.println("RO DataAbstract layer is configured.");

System.out.println("STEP 1: Login to DataService");
String RelativityConnectionStringTemplate = "User Id=\"%s\";Password=\"%s\";Domain=\"%s\";Schema=\"%s\"";
String lLoginString = String.format(RelativityConnectionStringTemplate,
        "simple", "simple", "DASamples", "Simple");
System.out.println(String.format("Login string is %s", lLoginString));
Boolean lLogged = lDataAdapter.login(lLoginString);

if (lLogged) {
    System.out.println("Login has been successful. Going further...");
} else {
    System.out
            .println("Cannot login. Please check your user name  and password. Exiting...");
    return;
}

Retrieving a Table (Step 2)

To retrieve a copy of a table from the schema there are a couple of different options.

In this sample we create a TableRequestInfoV5 object that means we can specify custom parameters for the data request. We pass "-1" to setMaxRecords to request all of the table's records, if a positive value is passed then the number of records is limited to that. To request the schema to be returned in the results we pass "true" to setIncludeSchema. Finally to selectively retrieve fields for a given row, we need to pass the field names in a StringArray to the setDynamicSelectFieldNames method and tell the RemoteDataAdapter to use Dynamic Select by passing "true" to setDynamicSelect.

The next step is create a DataTable which will hold the results from the server. The name passed to the constructor should be the name of the table you wish to retrieve data from.

Finally to retrieve the data we pass the TableRequestInfoV5 and DataTable to the fill method of RemoteDataAdapter which executes in a synchronous fashion delaying further processing until the request completes. Once the data has been retrieved it is printed to the console.

An alternative option is shown in Working Asynchronously with the Remote Data Adapter.

System.out.println("STEP 2. Select the data (List of departments) ...");

TableRequestInfoV5 lRequestInfo = new TableRequestInfoV5();
lRequestInfo.setMaxRecords(-1); // no limits - return all records
lRequestInfo.setIncludeSchema(true); // update schema in the result data
                                     // table to match recieved data
                                     // (not necessarily).
lDataAdapter.setDynamicSelect(true);
lRequestInfo.setDynamicSelectFieldNames(new StringArray(new String[] {
        "DepId", "DepName", "DepPhone" }));

DataTable lClientsData = new DataTable("Deps");

lDataAdapter.fill(lClientsData, lRequestInfo);

System.out.println(DataTableExtension.LogToString(lClientsData));

Inserting a row (Step 3)

Each table is made up of multiple DataRow objects where each one representing a row in the schema table and its columns. To add a new row to the table, we use the addNewRow method of DataTable which appends a new row to the table and returns a reference to it. The values for all of the columns will be initially set to null, except for any columns that use an AutoInc value in which case they will be assigned a negative value.

To set a value for a field, you use the setField method passing in the name of the field and assigning a string object as a value. Here we set the DepName field to "Security" and the DepPhone field to "(873)000-00-00". The DepId field uses AutoInc and is assigned -1 which you can see in the example output at the bottom of this page.

At this stage only the local copy of the DataTable has the new row, to update the server to match the local copy we need to apply those changes to the server using the applyChanges. This method extracts a delta of changes from the given table and passes it to the server, then it receives an incoming delta of changes and merges those changes into the local table. This means when we check the value DepId after applying the changes it now has a value of 8 (in the output below) rather than -1.

System.out.println("STEP 3. Insert a new row (Security department)...");

DataRow lDataRow = lClientsData.addNewRow();

lDataRow.setField("DepName", "Security");
lDataRow.setField("DepPhone", "(873)000-00-00");

System.out.println(DataTableExtension.LogToString(lClientsData));
System.out.println("Apply changes....");
try {
    lDataAdapter.applyChanges(lClientsData);
    System.out
            .println(String
                    .format("Changes has been applied. New department has got an ID %s",
                            lDataRow.getField("DepId").toString()));
} catch (Exception Ex) {
    System.out.println(Ex.getMessage());
}

System.out.println(DataTableExtension.LogToString(lClientsData));

Updating a row (Step 4)

To update the a field, we do the same as in Step 3; we assign a new value to the DataRow for the particular field name and then apply the changes to the server. Here we update the DepPhone field to "(873)456-77-77" which only replaces the local value until applyChanges is called.

System.out
        .println("STEP 4. Modify row (Change phone for added department)...");
lDataRow.setField("DepPhone", "(873)456-77-77");

System.out.println("Apply changes....");
try {
    lDataAdapter.applyChanges(lClientsData);
    System.out.println("Changes has been applied");
} catch (Exception Ex) {
    System.out.println(Ex.getMessage());
}

System.out.println(DataTableExtension.LogToString(lClientsData));

Deleting a row (Step 5)

To delete a row from a table you need to use the delete method of the DataRow object. To delete the row on the server, we need to call applyChanges which will update the server and then the local table accordingly.

System.out.println("STEP 5. Delete row (Remove added department)...");
lDataRow.delete();

System.out.println("Apply changes....");
try {
    lDataAdapter.applyChanges(lClientsData);
    System.out.println("Changes has been applied");
} catch (Exception Ex) {
    System.out.println(Ex.getMessage());
}

System.out.println(DataTableExtension.LogToString(lClientsData));

Example Output

This is an example of the output you will see when the sample is run. In Step 2 you can see there are two rows in the Deps table, in Step 3 there are now three rows and that in Step 4 the phone number for the Security department has changed. Lastly in Step 5 there are once again only two rows.

Simple Data Operation sample has been started.
Target URL is http://localhost:7099/bin
RO SDK layer is configured.
RO DataAbstract layer is configured.
STEP 1: Login to DataService
Login string is User Id="simple";Password="simple";Domain="DASamples";Schema="Simple"
Login has been successful. Going further...
STEP 2. Select the data (List of departments) ...

Table: Deps (2 rows from 2)
|------------------------------------------------------|
|DepId         |DepName            |DepPhone           |
|------------------------------------------------------|
|1             |Sales              |(873)456-78-99     |
|2             |Incomes            |(873)456-78-88     |
|------------------------------------------------------|


STEP 3. Insert a new row (Security department)...

Table: Deps (3 rows from 3)
|------------------------------------------------------|
|DepId         |DepName            |DepPhone           |
|------------------------------------------------------|
|1             |Sales              |(873)456-78-99     |
|2             |Incomes            |(873)456-78-88     |
|-1            |Security           |(873)000-00-00     |
|------------------------------------------------------|


Apply changes....
Changes has been applied. New department has got an ID 3

Table: Deps (3 rows from 3)
|------------------------------------------------------|
|DepId         |DepName            |DepPhone           |
|------------------------------------------------------|
|1             |Sales              |(873)456-78-99     |
|2             |Incomes            |(873)456-78-88     |
|3             |Security           |(873)000-00-00     |
|------------------------------------------------------|


STEP 4. Modify row (Change phone for added department)...
Apply changes....
Changes has been applied

Table: Deps (3 rows from 3)
|------------------------------------------------------|
|DepId         |DepName            |DepPhone           |
|------------------------------------------------------|
|1             |Sales              |(873)456-78-99     |
|2             |Incomes            |(873)456-78-88     |
|3             |Security           |(873)456-77-77     |
|------------------------------------------------------|


STEP 5. Delete row (Remove added department)...
Apply changes....
Changes has been applied

Table: Deps (2 rows from 2)
|------------------------------------------------------|
|DepId         |DepName            |DepPhone           |
|------------------------------------------------------|
|1             |Sales              |(873)456-78-99     |
|2             |Incomes            |(873)456-78-88     |
|------------------------------------------------------|


DONE! Please press return to exit.