Working with Batches

Batch Updating

You can update objects that are persisted in an object store by using a batch operation. After an action is performed on an object (such as check-in, or delete), you add the object to an UpdatingBatch instance, which is in contrast to individual (non-batched) operations on objects, in which you save the object to run the pending update to the object. After you add to the UpdatingBatch instance all the objects to be updated, you then call the updateBatch method on the instance to run the pending batch update.

This operation is a transactional operation; all the calls in the batch succeed or fail as a unit. If failure occurs, the transaction is rolled back and an exception is thrown.

The general sequence for a batch update operation is as follows:

Java™ Example


// Get an instance of the UpdatingBatch class.
Domain myDomain = os.get_Domain();

// The RefreshMode parameter is set to REFRESH to indicate that the property cache for 
// this instance is to be refreshed with the updated data.
UpdatingBatch ub = UpdatingBatch.createUpdatingBatchInstance(myDomain, RefreshMode.REFRESH);

// Add object updates to the batch.
// Assume, in this case, that these documents have already been checked out.
// No property filters are used (filter parameters are null).
Document doc1 = Factory.Document.fetchInstance(os, new Id("{F905DBD6-5A69-4252-9985-2D3DD28D7FBA}"), null);
Document doc2 = Factory.Document.fetchInstance(os, new Id("{35026B90-B443-40CA-B5C3-66BEAD13E2B7}"), null);

// First update to be included in batch.
doc1 = (Document) doc1.get_Reservation();
doc1.checkin(null, CheckinType.MAJOR_VERSION);

// Second update to be included in batch.
doc2 = (Document) doc2.get_Reservation();
doc2.checkin(null, CheckinType.MAJOR_VERSION); 

// Third update to be included in batch. Sets the document title and assigns the 
// specified property values (Properties.putValue) to the retrieved properties for the 
// doc (the inherited EngineObject.getProperties). 
doc1.getProperties().putValue("DocumentTitle", "doc1"); 

// Fourth update to be included in batch.
doc2.getProperties().putValue("DocumentTitle", "doc2"); 

// Adds all four updates (to the two Document objects) to the UpdatingBatch instance. 
ub.add(doc1, null);  
ub.add(doc2, null);  

// Execute the batch update operation.
ub.updateBatch();
 

C# Example


// Get an instance of the UpdatingBatch class.
IDomain myDomain = os.Domain;

// The RefreshMode parameter is set to REFRESH to indicate that the property cache for 
// this instance is to be refreshed with the updated data.
UpdatingBatch ub = UpdatingBatch.CreateUpdatingBatchInstance(myDomain, FileNet.Api.Constants.RefreshMode.REFRESH);

// Add object updates to the batch.
// Assume, in this case, that these documents have already been checked out.
// No property filters are used (filter parameters are null).
IDocument doc1 = Factory.Document.FetchInstance(os, new Id("{CF0BE923-DCFD-4832-8CE0-001E4A111E25}"), null);
IDocument doc2 = Factory.Document.FetchInstance(os, new Id("{A25A8FB0-D4EF-4690-83BB-41F7EB98D631}"), null);

// First update to be included in batch.
doc1 = (IDocument) doc1.Reservation;
doc1.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);

// Second update to be included in batch.
doc2 = (IDocument) doc2.Reservation;
doc2.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);

// Third update to be included in batch. Sets the document title and assigns the 
// specified property values (Properties.putValue) to the retrieved properties for the 
// doc (the inherited EngineObject.getProperties).     
doc1.Properties.GetProperty("DocumentTitle").SetObjectValue("doc1");

// Fourth update to be included in batch.
doc2.Properties.GetProperty("DocumentTitle").SetObjectValue("doc2");

// Adds all four updates (to the two Document objects) to the UpdatingBatch instance. 
ub.Add(doc1, null);
ub.Add(doc2, null);

// Execute the batch update operation.
ub.UpdateBatch();
 

Example: Batch Update to Delete Objects

The following example illustrates a batch update operation to delete objects:

Java Example


public static void updatePendingDeletion(Domain myDomain) throws Exception
{
    PropertyFilter myOSFilter = null;
    String myOS = "LaurelTree";
    ObjectStore os = Factory.ObjectStore.fetchInstance(myDomain, myOS, myOSFilter);
    
    // The RefreshMode parameter indicates that the property cache for this instance is to be 
    // refreshed with the updated data.
    UpdatingBatch ub = UpdatingBatch.createUpdatingBatchInstance(myDomain, RefreshMode.NO_REFRESH);
    
    // Get the documents. Calls findDocs routine below to get up to three documents in the 
    // specified object store having a DocumentTitle of "Batch Deleting Example". These 
    // documents might or might not be currently checked out.
    Document[] docArr = findDocs(os, "Batch Deleting Example", false, 3);
    Document doc1 = docArr[0];
    Document doc2 = docArr[1];
    Document doc3 = docArr[2];
                        
    // Override update sequence number check.
    doc1.setUpdateSequenceNumber(null);
    doc2.setUpdateSequenceNumber(null);
    doc3.setUpdateSequenceNumber(null);
    
    // The inherited IndependentlyPersistedObject.delete method adds this pending action.
    doc1.delete(); 
    doc2.delete(); 
    doc3.delete(); 
    
    // Adds the Document objects with pending deletions to the UpdatingBatch instance.
    ub.add(doc1, null);  
    ub.add(doc2, null);  
    ub.add(doc3, null);  
    ub.updateBatch();
        
}
        
// Uses SearchSQL and SearchScope to find documents of the specified title, then fetches 
// these Document objects. The onlyReservation parameter indicates whether or not you 
// want only documents that are currently checked out.
static Document[] findDocs(
    ObjectStore os, 
    String docTitle, 
    boolean onlyReservation, 
    int findCount) throws Exception
{
    // Declare document array.
    Document[] docArr = new Document[findCount];
        
    // Build the SQL statement.
    String sql = "select d.this from Document d " + 
        "where DocumentTitle = '" + docTitle + "'";
    SearchSQL searchSQL = new SearchSQL();
    searchSQL.setQueryString(sql);
        
    SearchScope searchScope = new SearchScope(os);
    IndependentObjectSet objectSet = searchScope.fetchObjects(searchSQL, null, null, null);
        
    int count = 0;
    Iterator iter = objectSet.iterator();
    while (iter.hasNext() == true && count < findCount)
    {
        Document doc = (Document) iter.next();
        doc.refresh();
        boolean statusReservation = false;
        if (doc.get_VersionStatus() == VersionStatus.RESERVATION)
        {
            statusReservation = true;
        }
            
        if (onlyReservation == false || statusReservation == true)
        {
            System.out.println("Document: " + doc.get_Id().toString());
            docArr[count] = doc;
            count++;                           
        }
    }
        
    // Throw an exception if unable to find documents.
    if (count < findCount)
    {
        String message = "Unable to find " + findCount + " ";
        if (onlyReservation == true)
        {
            message = message + "reserved ";
        }
        message = message + " documents with title '" + docTitle + "'"; 
        throw new Exception(message);
    }
        
    // Return document array.
    return docArr;
}
 

C# Example


public static void UpdatePendingDeletion(IDomain myDomain)
{
    PropertyFilter myOSFilter = null;
    string myOS = "LaurelTree";
    IObjectStore os = Factory.ObjectStore.FetchInstance(myDomain, myOS, myOSFilter);

    UpdatingBatch ub = UpdatingBatch.CreateUpdatingBatchInstance(myDomain, RefreshMode.NO_REFRESH);
            
    IDocument[] docArr = findDocs(os, "Batch Deleting Example", false, 3);
    IDocument doc1 = docArr[0];
    IDocument doc2 = docArr[1];
    IDocument doc3 = docArr[2];

    doc1.SetUpdateSequenceNumber(null);
    doc2.SetUpdateSequenceNumber(null);
    doc3.SetUpdateSequenceNumber(null);

    doc1.Delete();
    doc2.Delete();
    doc3.Delete();

    ub.Add(doc1, null);
    ub.Add(doc2, null);
    ub.Add(doc3, null);

    ub.UpdateBatch();
}

static IDocument[] findDocs(IObjectStore os, string docTitle, bool onlyReservation, int findCount)
{
    IDocument[] docArr = new IDocument[findCount];
    string sql = "select d.this from Document d " +
                        "where DocumentTitle = '" + docTitle + "'";
    SearchSQL searchSQL = new SearchSQL();
    searchSQL.SetQueryString(sql);
    SearchScope searchScope = new SearchScope(os);
    IIndependentObjectSet objectSet = searchScope.FetchObjects(searchSQL, null, null, null);

    int count = 0;
    foreach (IDocument doc in objectSet)
    {
        if (count < findCount)
        {
            doc.Refresh();
            bool statusReservation = false;
            if (doc.VersionStatus == VersionStatus.RESERVATION)
            {
                statusReservation = true;
            }
            if (onlyReservation == false || statusReservation == true)
            {
                System.Console.WriteLine("Document: " + doc.Id.ToString());
                docArr[count] = doc;
                count++;
            }
        }
    }

    if (count < findCount)
    {
        string message = "Unable to find " + findCount + " ";
        if (onlyReservation == true)
        {
            message = message + "reserved ";
        }
        message = message + " documents with title '" + docTitle + "'";
        throw new System.Exception(message);
    }
    return docArr;
}
 

Pending Batch Updates

You can find out whether a batch operation has run (the updateBatch method called) by calling the UpdatingBatch.hasPendingExecute method.

Batch Retrieving

You can retrieve from the Content Engine any object that is subclassed from an IndependentObject object by using a batch retrieval operation. As opposed to batch updating, this operation is not a transactional operation. Each object retrieval succeeds or fails individually.

Any subsequent changes to the objects retrieved in the batch are done in place (only references to the objects in the batch are retrieved).

The general sequence for a batch retrieval operation is as follows:

Java Example


// Get an instance of the RetrievingBatch class.
Domain myDomain = os.get_Domain();
RetrievingBatch rb = RetrievingBatch.createRetrievingBatchInstance(myDomain);

// Add objects to the batch. New objects are used for the purposes here.
Document doc1 = Factory.Document.createInstance(os, null);
doc1.checkin(null, null);
doc1.save(RefreshMode.NO_REFRESH);

Document doc2 = Factory.Document.createInstance(os, null);
doc2.checkin(null, null);
doc2.save(RefreshMode.NO_REFRESH);

// No filtering is used.
rb.add(doc1, null);  
rb.add(doc2, null);  

// Execute the batch retrieval operation:
rb.RetrieveBatch();

C# Example


// Get an instance of the RetrievingBatch class.
IDomain myDomain= os.Domain;
RetrievingBatch rb = RetrievingBatch.CreateRetrievingBatchInstance(myDomain);

// Add objects to the batch. New objects are used for the purposes here.
IDocument doc1 = Factory.Document.CreateInstance(os, null);
doc1.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);
doc1.Save(RefreshMode.NO_REFRESH);

IDocument doc2 = Factory.Document.CreateInstance(os, null);
doc2.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);
doc2.Save(RefreshMode.NO_REFRESH);

// No filtering is used.
rb.Add(doc1, null);
rb.Add(doc2, null);

rb.RetrieveBatch();

Checking for Retrieval Exceptions

After your run a batch retrieval operation, you can find out whether any of the object retrievals generated an exception by calling the hasExceptions method to return a Boolean value. However, if you want to be able to do something based on whether a particular object retrieval threw an exception, you need to get the collection of BatchItemHandle instances, and iterate them to find out which object retrieval threw an exception. For example:

Java Example


Iterator iterator1 = rb.getBatchItemHandles(null).iterator();
while (iterator1.hasNext()) {
    BatchItemHandle obj = (BatchItemHandle) iterator1.next();
    if (obj.hasException()) 
    {
        // Displays the exception, for the purpose of brevity here.
        EngineRuntimeException thrown = obj.getException();
        System.out.println("Exception: " + thrown.getMessage());
    }
}                       

C# Example


foreach (IBatchItemHandle obj in rb.GetBatchItemHandles(null))
{
    if (obj.HasException())
    {
        FileNet.Api.Exception.EngineRuntimeException thrown = obj.GetException();
        System.Console.WriteLine("Exception: " + thrown.Message);
    }
}