Thank you for the help. Here’s the code sample.

Note: the edit control for this web site can’t tell the difference between an annotation with the @ sign or a @mention and only allows for 2 mentions in a post (at least for me). Therefore, at signs are wrapped in parenthesis. Remove the () for the actual code example.

(@)Entity(“xtransactions”)
(@)Indexes({
(@)Index(“Customer, Timestamp”),
(@)Index(“Timestamp”)
})
public class XTransactionData {
(@)Id
public ObjectId Id;
(@)Reference(ignoreMissing=true)
public CustomerData Customer;
public Date Timestamp;
public byte Sample;
public byte SampleEncrypted;
public String StorageReference;

public void delete() throws Exception {
	if (Id != null) {
		Datastore ds = Support.getDatastore();
		try {
		
			// Delete the audio from cloud storage
			if (!(Customer.AudioStorageMethod == null || Customer.AudioStorageMethod.equals("Local"))) {
				if (StorageReference != null) {
					Support.removeAudioFromCloudStorage(StorageReference, Customer, "XAudio");
				}
			}
			
			// Delete the the XTransaction from the collection in Mongo
			System.out.println("Before Delete");
			WriteResult result = ds.delete(XTransactionData.class, Id);
			System.out.println("After Delete");
			System.out.println("Error: " + result.getError());
			System.out.println("N: " + result.getN());
			System.out.println("Last Error: " + result.getLastError());
		} finally {
			System.out.println("Closing X data store");
			Support.closeDatastore(ds);
		}
	}
}

}


(@)Entity(“ytransactions”)
(@)Indexes({
(@)Index(“Customer, Timestamp”),
(@)Index(“Timestamp”)
})

public class YTransactionData {

(@)Id
public ObjectId Id;
(@)Reference(ignoreMissing=true)
public CustomerData Customer;
public Date Timestamp;
public byte[] Sample;
public byte[] SampleEncrypted;
public String StorageReference;
...

// The same functionality as XTransactionData
public void delete() throws Exception {}

}


(@)Entity(“customers”)
(@)Indexes({
(@)Index(
fields = (@)Field(value=“Name”),
options = (@)IndexOptions(unique=true)
),
(@)Index(
fields = (@)Field(value=“CalloutUsername”)
)
})
public class CustomerData {
(@)Id
public ObjectId Id;
public String Name;
public String Alias;
public String DemoAlias;
public String Description;

}


public DeleteCustomer(String customerid) {
DeleteXTransactionForCustomer(customerid);

DeleteYTransactionForCustomer(customerid);

DeleteUsers(customerid);

DeleteCustomerFinal(customerid);

}


// Delete the XTransaction for this customer from the X collection
// DeleteYTransactionForCustomer is identical except for the Y variant transactions
public void DeleteXTransactionForCustomer(String customerid) {
Util.LogMessage(“Deleting X transactions”);
try {
Datastore ds = Support.getDatastore();
try {
CustomerData customer = CustomerData.get(new ObjectId(customerid));
if (customer != null) {
long count;
// Create a query for the XTransactionData
Query classtransactionquery = ds.createQuery(XTransactionData.class);

			// Filter on the Customer
			classtransactionquery.and(classtransactionquery.criteria("Customer").equal(customer));

			// Set the batch size, issue the request, and grab the iterator
			Iterator<XTransactionData> classtransactionlist = classtransactionquery.batchSize(1000).fetch().iterator();
			count = 0;

			// Loop over all the returned records
			while (classtransactionlist.hasNext()) {
				XTransactionData transactiondata = classtransactionlist.next();
				
				// Delete one at a time to ensure all blob audio is removed
				transactiondata.delete();		    					

				// Increment the count
				count++;

				// Limit the output
				if (count % 1000 == 0) {
					Util.LogMessage("Deleted " + count + " X transactions so far");
				}
			}

			// Update the output to include any additional X transactions 
			Util.LogMessage("Deleted " + count + " X transaction(s)");
		}
	} finally {
		Support.closeDatastore(ds);
	}
} catch (Exception ex) {
	Util.LogException(ex);
}

}


public void DeleteUsers(String customerid) {
Util.LogMessage(“Deleting users”);
try {
Datastore ds = Support.getDatastore();
try {
CustomerData customer = CustomerData.get(new ObjectId(customerid));
if (customer != null) {
long count;
// Create a query for the UserData
Query userquery = ds.createQuery(UserData.class);

			// Filter on the CustomerId
			userquery.and(userquery.criteria("CustomerId").equal(customer));

			// Set the batch size, issue the request, and grab the iterator
			Iterator<UserData> userlist = userquery.batchSize(1000).fetch().iterator();
			count = 0;

			// Loop over all the returned records
			while (userlist.hasNext()) {
				UserData userdata = userlist.next();
				
				// Delete one at a time to ensure all blob audio is removed
				userdata.delete();

				// Increment the count
				count++;

				// Limit the output
				if (count % 1000 == 0) {
					Util.LogMessage("Deleted " + count + " users so far");
				}
			}

			// Update the output to include any additional X transactions 
			Util.LogMessage("Deleted " + count + " user(s)");
		}
	} finally {
		Support.closeDatastore(ds);
	}
} catch (Exception ex) {
	Util.LogException(ex);
}

}


// Delete the customer in Mongo.
// After this is called, any remaining Y transactions now have a reference to a non-existent customer.
public void DeleteCustomerFinal(String customerid) {
try {
Datastore ds = Support.getDatastore();
try {
CustomerData customer = CustomerData.get(new ObjectId(customerid));
if (customer != null) {
Util.LogMessage(“Deleting customer”);
ds.delete(CustomerData.class, customer.Id);
} else {
Util.LogMessage(“Customer " + customerid + " could not be found”);
}
} finally {
Support.closeDatastore(ds);
}
} catch (Exception ex) {
Util.LogException(ex);
}
}