Andy in the Cloud

From BBC Basic to Force.com and beyond…


8 Comments

Preview: Demo of Apex Code Analysis using the Tooling API and Canvas

This weekend I’ve been fleshing out the code for my second Dreamforce 2013 session. I’ve been having a lot of fun with various technologies to create the following demo which I’ve shared a short work in progress video below. The JQuery plugin doing the rendering is js-mindmap, it’s got some quirks I’ve discovered so far, but I’m sticky with it for now!

The session highlights the Tooling API via this tool which can be installed directly into your Salesforce environment via the wonderful Salesforce Canvas technology! This is proposed session abstract …

Dreamforce 2013 Session: Apex Code Analysis using the Tooling API and Canvas

The Tooling API provides powerful new ways to manage your code and get further insight into how its structured. This session will teach you how to use the Tooling API and its Symbol Table to analyse your code using an application integrated via Force.com Canvas directly into your Salesforce org — no command line or desktop install required! Join us and take your knowledge of how your Apex code is really structured to the next level!

Technologies involved so far…

I’ve also found the excellent ObjectAid Eclipse plugin (which is sadly a Java source code only tool) to explore the Tooling API data structures in much more detail than the Salesforce documentation currently offers, especially in respect to the SymbolTable structure. I’ll be sharing full code and discussing the following diagram in more detail in my session! In the meantime I’d love to know your thoughts and other ideas around the Tooling API!

Tooling API


7 Comments

Ideas for Apex Enterprise Patterns Dreamforce 2013 Session!

ideaguy

Update: Dreamforce is over for another year! Thanks to everyone who supported me and came along to the session. Salesforce have now uploaded a recording of the session here and can find the slides here.

As part of this years Dreamforce 2013 event I will be once again running a session on Apex Enterprise Patterns, following up on my recent series of developer.force.com articles. Here is the current abstract for the session, comments welcome!

Building Strong Foundations: Apex Enterprise Patterns “Any structure expected to stand the test of time and change, needs a strong foundation! Software is no exception, engineering your code to grow in a stable and effective way is critical to your ability to rapidly meet the growing demands of users, new features, technologies and platform features. You will take away architect level design patterns to use in your Apex code to keep it well factored, easier to maintain and obey platform best practices. Based on a Force.com interpreation of Martin Fowlers Enterprise Architecture Application patterns and the practice of Separation of Concerns.” (Draft)

I’ve recently started to populated a dedicated Github repository that contains only the working sample code (with the library code in separate repo). So that i can build out a real working sample application illustrating in practical way the patterns in action. It already covers a number of features and use cases such as…

  • Layering Apex logic by applying Separation of Concerns
  • Visualforce controllers and the Service Layer
  • Triggers, validation, defaulting and business logic encapsulation via Domain layer
  • Applying object orientated programming inheritance and interfaces via Domain layer
  • Managing DML and automatic relationship ‘stitching’ when inserting records via Unit Of Work pattern
  • Factoring, encapsulating and standardising SOQL query logic via Selector layer

The following are ideas I’ll be expanding on in the sample application in preparation for the session…

  • Batch Apex and Visualforce Remoting (aka JavaScript callers) and the Service Layer
  • Apex testing without SOQL and DML via the Domain Layer
  • Exposing a custom application API, such as REST API or Apex API via Service Layer
  • Reuse and testing SOQL query logic in Batch Apex context via Selector Layer
  • Rich client MVC frameworks such as AngularJS and Service Side SOC

What do you think and what else would you like to see and discuss in this session?

Feel free to comment on this blog below, tweet me, log it on Github or however else you can get in touch.


10 Comments

Apex Enterprise Patterns – Selector Layer

A major theme in this series on Apex Enterprise Patterns has been ensuring a good separation of concerns, making large complex enterprise level code bases more clear, self documenting, adaptable and robust to change, be that refactoring or functional evolution over time.

In the past articles in this series we have seen Service logic that orchestrates how functional sub-domains work together to form the key business processes your application provides. Domain logic breaks down the distinct behaviour of each custom object in your application by bring the power of Object Orientated Programming into your code.

This article introduces the Selector, a layer of code that encapsulates logic responsible for querying information from your custom objects and feeding it into your Domain and Service layer code as well as Batch Apex jobs.

Selectors

You can read the rest of this article on the wiki.developerforce.com here, enjoy!

Series Summary

This completes the current series of articles on Apex Enterprise Patterns. The main goal was to express a need for Separation of Concerns to help make your Apex logic on the platform live longer and maintain its stability. In presenting three of the main patterns I feel help deliver this. If nothing else, I’d like to think you have started to think more about SOC, even if it’s just class naming. Though hopefully beyond that if you use some of the articles’ various base classes great, please feel free to contribute to them. If you don’t, or decide to skip some or use a different pattern implementation that’s also fine, thats what patterns are all about. If you do, I’d love to hear about other implementations.

Martin Fowler’s excellent patterns continue to be referenced on platforms, new and old. I’ve very much enjoyed adapting them to this platform and using them to effect better adoption of Force.com platform best practices along the way. Thanks to everyone for all the great feedback, long may your code live!


12 Comments

Batch Worker, Getting more done with less work…

Batch Apex has been around on the platform for a while now, but I think its fair to say there is still a lot of mystery around it and with that a few baked in assumptions. One such assumption I see being made is that its driven by the database, specifically the records within the database determine the work to be done.

construction_workerAs such if you have some work you need to get done that won’t fit in the standard governors and its not immediately database driven, Batch Apex may get overlooked in favour of @future which on the surface feels like a better fit as its design is not database linked in anyway .  Your code is just an annotation away to getting the addition power it needs! So why bother with the complexities of Batch Apex?

Well for starters, Batch Apex gives you an ID to trace the work being done and thus the key to improving the user experience while the user waits. Secondly, if any of your parameters are lists or arrays to such methods, your already having to consider again scalability. Yes, you say, but its more fiddly than @future isn’t it?

In this blog I’m going to explore a cool feature of the Batch Apex that often gets overlooked. Using it to implement a worker pattern giving you the kind of usability @future offers with the additional scalability and traceability of Batch Apex without all the work. If your not interested in the background, feel free to skip to the Batch Worker section below!

IMPORTANT NOTE: The alternative approach described here is not designed as a replacement to using Batch Apex against the database using QueryLocator. Using QueryLocator gives access to 50m records, where as the Iterator usage only 50k. Thus the use cases for the Batch Worker are more aligned with smaller jobs perhaps driven by end user selections or stitching together complex chunks of work together.

Well I didn’t know that! (#WIDKT)

First lets review something you may not have realised about implementing Batch Apex. The start method can return either a QueryLocator or something called Iterable. You can implement your own iterators, but what is actually not that clear is that Apex collections/lists implement Iterator by default!

Iterable<String> i = new List<String> { 'A', 'B', 'C' };

With this knowledge, implementing Batch Apex to iterate over a list is now as simple as this…

public with sharing class SimpleBatchApex implements Database.Batchable<String>
{
	public Iterable<String> start(Database.BatchableContext BC)
	{
		return new List<String> { 'Do something', 'Do something else', 'And something more' };
	}

	public void execute(Database.BatchableContext info, List<String> strings)
	{
		// Do something really expensive with the string!
		String myString = strings[0];
	}

	public void finish(Database.BatchableContext info) { }
}

// Process the String's one by one each with its own governor context
Id jobId = Database.executeBatch(new SimpleBatchApex(), 1);

The second parameter of the Database.executeBatch method is used to determine how many items from the list are pass to each execute method invocation made by the platform. To get the maximum governors per item and match that of a single @future call, this is set 1.  We can also implement Batch Apex with a generic data type know as Object. Which allows you to process different types or actions in one job, more about this later.

public with sharing class GenericBatchApex implements Database.Batchable<Object>
{
	public Iterable<Object> start(Database.BatchableContext BC) { }

	public void execute(Database.BatchableContext info, List<Object> listOfAnything) { }

	public void finish(Database.BatchableContext info) { }
}

A BatchWorker Base Class

The above simplifications are good, but I wanted to further model the type of flexibility @future gives without dealing with the Batch Apex mechanics each time. In designing the BatchWorker base class used in this blog i wanted to make its use as easy as possible. I’m a big fan of the fluent API model and so if you look closely you’ll see elements of that here as well. You can view the full source code for the base class here, its quite a small class though, extending the concepts above to make a more generic Batch Apex implementation.

First lets take another look at the string example above, but this time using the BatchWorker base class.

public with sharing class MyStringWorker extends BatchWorker
{
	public override void doWork(Object work)
	{
		// Do something really expensive with the string!
		String myString = (String) work;
	}
}

// Process the String's one by one each with its own governor context
Id jobId =
	new MyStringWorker()
            .addWork('Do something')
            .addWork('Do something else')
            .addWork('And something more')
            .run()
            .BatchJobId;

Clearly not everything is as simple as passing a few strings, after all @future methods can take parameters of varying types. The following is a more complex example showing a ProjectWorker class. Imagine this is part of a Visualforce controller method where the user is presented a selection of projects to process with a date range.

	// Create worker to process the project selection
	ProjectWorker projectWorker = new ProjectWorker();
		
	// Add the work to the project worker
	for(SelectedProject selectedProject : selectedProjects)		
		projectWorker.addWork(startDate, endDate, selectedProject.projectId);
			
	// Start the workder and retain the job Id to provide feedback to the user
	Id jobId = projectWorker.run().BatchJobId;		

Here is how the ProjectWorker class has been implemented, once again it extends the BatchWorker class. But this time it provides its own addWork method which takes the parameters as you would normally describe them. Then internally wraps them up in a worker data class. The caller of the class, as you’ve seen above is is not aware of this.

public with sharing class ProjectWorker extends BatchWorker
{	
	public ProjectWorker addWork(Date startDate, Date endDate, Id projectId)
	{
		// Construct a worker object to wrap the parameters		
		return (ProjectWorker) super.addWork(new ProjectWork(startDate, endDate, projectId));
	}
	
	public override void doWork(Object work)
	{
		// Parameters
		ProjectWork projectWork = (ProjectWork) work;
		Date startDate = projectWork.startDate;
		Date endDate = projectWork.endDate;
		Id projectId = projectWork.projectId;		
		// Do the work
		// ...
	}
	
	private class ProjectWork
	{
		public ProjectWork(Date startDate, Date endDate, Id projectId)
		{
			this.startDate = startDate;
			this.endDate = endDate;
			this.projectId = projectId;
		}
		
		public Date startDate;
		public Date endDate;
		public Id projectId;
	}
}

As a final example, recall the fact that Batch Apex can process a list of generic data types. The BatchProcess base class uses this to permit the varied implementations above. It can also be used to create a worker class that can do more than one thing. The equivalent of implementing two @future methods, accept that its managed as one job.

public with sharing class ProjectMultiWorker extends BatchWorker 
{
	// ...

	public override void doWork(Object work)
	{
		if(work instanceof CalculateCostsWork)
		{
			CalculateCostsWork calculateCostsWork = (CalculateCostsWork) work;
			// Do work 
			// ...					
		}
		else if(work instanceof BillingGenerationWork)
		{
			BillingGenerationWork billingGenerationWork = (BillingGenerationWork) work;
			// Do work
			// ...		
		}
	}
}

// Process the selected Project 
Id jobId = 
	new ProjectMultiWorker()
		.addWorkCalculateCosts(System.today(), selectedProjectId)
		.addWorkBillingGeneration(System.today(), selectedProjectId, selectedAccountId)
		.run()
		.BatchJobId;

Summary

Hopefully I’ve provided some insight into new ways to access the power and scalability of Batch Apex for use cases which you may not have previously considered or perhaps used less flexible @future annotation. Keep in mind that using Batch Apex with Iterators does reduce the number of items it can process to 50k, as apposed to the 50m when using database query locator. At the end of the day if you have more than 50k work items, your probably wanting to go down the database driven route anyway. I’ve shared all the code used in this article and some I’ve not shown in this Gist.

Post Credits
Finally, I’d like to give a nod to an past work associate of mine, Tony Scott, who has taken this type of approach down a similar path, but added process control semantics around it. Check out his blog here!


38 Comments

How To: Call Apex code from a Custom Button

Screen Shot 2013-07-16 at 08.21.48‘How do I call Apex code from a Custom Button?’ is a simple question, however the answer is covered across various developers guides and general documentation…

Having answered a number of questions on StackExchange over the year or so I’ve been active on it, I thought I’d compile this how to guide as reference peace. Of course its littered with links to the  excellent Salesforce documentation, so please do dig into those as well.

The steps are as follows to add either a Detail or a List View  button (as illustrated below) to Standard or Custom Object. It’s well worth going through the topics and general reference guides I’ve linked in more detail. I’ve given some examples of my own, but there are also plenty of them in the help topics I’ve linked to if you need more examples.

Screen Shot 2013-07-16 at 09.13.00Screen Shot 2013-07-16 at 09.12.46

Steps to Create a Custom Button that runs Apex Code

  1. Create a Apex Extension Controller class as shown in the examples below.
  2. Create a Visualforce page, using the ‘standardController‘ and ‘extensions‘ attributes on apex:page *
  3. Create a Custom Button using the Visualforce page as its Content Source
  4. Add the Custom Button to the appropriate Layout of the object
  5. Use either the ‘action‘ attribute (see warning below) or apex:commandButton‘s on your page to invoke Apex logic.


*
 You must also use the ‘recordSetVar‘ attribute on apex:page if you wish to create List View button.

Detail Page Custom Button Template

Example page and class using apex:commandButton to invoke the logic.

<apex:page standardController="Test__c" extensions="DetailButtonController">
    <apex:form >
        <apex:commandButton value="Do something" action="{!doSomething}"/>
    </apex:form>
</apex:page>

Apex controller code.

public with sharing class DetailButtonController
{
    private ApexPages.StandardController standardController;

    public DetailButtonController(ApexPages.StandardController standardController)
    {
        this.standardController = standardController;
    }

    public PageReference doSomething()
    {
        // Apex code for handling record from a Detail page goes here
        Id recordId = standardController.getId();
        Test__c record = (Test__c) standardController.getRecord();
        return null;
    }
}

Or to have your Apex logic run as soon as the user presses the Custom Button use the action attribute.

<apex:page standardController="Test__c" extensions="DetailButtonController"
           action="{!doSomething}">

To add the Custom Button should look something like this…

Screen Shot 2013-07-16 at 07.43.22

List View Custom Button Template

Example page and class, using apex:commandButton to invoke the logic.

<apex:page standardController="Test__c" extensions="ListButtonController"
           recordSetVar="TestRecords">
    <apex:form >
        <apex:commandButton value="Do something" action="{!doSomething}"/>
    </apex:form>
</apex:page>

Apex controller code.

public with sharing class ListButtonController
{
    private ApexPages.StandardSetController standardSetController;

    public ListButtonController(ApexPages.StandardSetController standardSetController)
    {
        this.standardSetController = standardSetController;
    }

    public PageReference doSomething()
    {
        // Apex code for handling records from a List View goes here
        List<Test__c> listViewRecords =
            (List<Test__c>) standardSetController.getRecords();
        List<Test__c> selectedListViewRecords =
            (List<Test__c>) standardSetController.getSelected();
        Boolean hasMore = standardSetController.getHasNext();
        return null;
    }
}

Or to have your Apex logic run as soon as the user presses the Custom Button use the action attribute.

<apex:page standardController="Test__c" extensions="ListButtonController"
           action="{!doSomething}" recordSetVar="TestRecords">

To add the Custom Button should look something like this…

Screen Shot 2013-07-16 at 07.43.58
WARNING: Use of ‘action’ attribute on apex:page and CSRF Attacks.

If you use the ‘action‘ attribute as per step 4 your Apex code will execute as soon as the Custom Button is pressed. However if your Apex code performs database updates this is considered unsecured as its possible that your code will be open to a CSRF attack. See this excellent topic from Salesforce for more information. If this is your case its better to use the apex:commandButton option and provide a confirmation button to your user before invoking your Apex code.

Since its Summer’13 release, Salesforce have started to add some support to allow us to use the ‘action’ attribute safely, which gives a better user experience since there is no need for a confirmation button. Currently however, the new ‘Require CSRF protection on GET requests‘ checkbox on the Visualforce page is only considered when the page is used to override the standard Delete button on an object. Hopefully support for Custom Button will arrive soon!

Update: 31st July 2013

Here is a great blog on sharing your Apex Controller class between Detail and List pages, Using one page and controller for both a “Detail Page Button” and a “List Button”.


42 Comments

Managing your DML and Transactions with a Unit Of Work

plumbing-equipment

A utility class I briefly referenced in this article was SObjectUnitOfWork. I promised in that article to discuss it in more detail, that time has come! Its main goals are.

  • Optimise DML interactions with the database
  • Provide transactional control
  • Simplify complex code that often spends a good portion of its time managing bulkificaiton and  ‘plumbing’ record relationships together.

In this blog I’m going to show you two approaches to creating a reasonably complex set of records on the platform, comparing the pros and cons of the traditional approach vs that using the Unit of Work approach.

Complex Data Creation and Relationships

Lets first look at a sample peace of code to create a bunch Opportunity records and related, Product, PricebookEntry and eventually OpportunityLine records. It designed to have a bit of a variable element to it, as such the number of lines per Opportunity and thus Products varies depending on which of the 10 Opportunties is being processed. The traditional approach is to do this a stage at a time, creating things and inserting things in the correct dependency order and associating child and related records via the Id’s generated by the previous inserts. Lists are our friends here!

			List opps = new List();
			List productsByOpp = new List();
			List pricebookEntriesByOpp = new List();
			List oppLinesByOpp = new List();
			for(Integer o=0; o<10; o++)
			{
				Opportunity opp = new Opportunity();
				opp.Name = 'NoUoW Test Name ' + o;
				opp.StageName = 'Open';
				opp.CloseDate = System.today();
				opps.add(opp);
				List products = new List();
				List pricebookEntries = new List();
				List oppLineItems = new List();
				for(Integer i=0; i<o+1; i++)
				{
					Product2 product = new Product2();
					product.Name = opp.Name + ' : Product : ' + i;
					products.add(product);
					PricebookEntry pbe = new PricebookEntry();
					pbe.UnitPrice = 10;
					pbe.IsActive = true;
					pbe.UseStandardPrice = false;
					pbe.Pricebook2Id = pb.Id;
					pricebookEntries.add(pbe);
					OpportunityLineItem oppLineItem = new OpportunityLineItem();
					oppLineItem.Quantity = 1;
					oppLineItem.TotalPrice = 10;
					oppLineItems.add(oppLineItem);
				}
				productsByOpp.add(products);
				pricebookEntriesByOpp.add(pricebookEntries);
				oppLinesByOpp.add(oppLineItems);
			}
			// Insert Opportunities
			insert opps;
			// Insert Products
			List allProducts = new List();
			for(List products : productsByOpp)
			{
				allProducts.addAll(products);
			}
			insert allProducts;
			// Insert Pricebooks
			Integer oppIdx = 0;
			List allPricebookEntries = new List();
			for(List pricebookEntries : pricebookEntriesByOpp)
			{
				List products = productsByOpp[oppIdx++];
				Integer lineIdx = 0;
				for(PricebookEntry pricebookEntry : pricebookEntries)
				{
					pricebookEntry.Product2Id = products[lineIdx++].Id;
				}
				allPricebookEntries.addAll(pricebookEntries);
			}
			insert allPricebookEntries;
			// Insert Opportunity Lines
			oppIdx = 0;
			List allOppLineItems = new List();
			for(List oppLines : oppLinesByOpp)
			{
				List pricebookEntries = pricebookEntriesByOpp[oppIdx];
				Integer lineIdx = 0;
				for(OpportunityLineItem oppLine : oppLines)
				{
					oppLine.OpportunityId = opps[oppIdx].Id;
					oppLine.PricebookEntryId = pricebookEntries[lineIdx++].Id;
				}
				allOppLineItems.addAll(oppLines);
				oppIdx++;
			}
			insert allOppLineItems;

Lists and Maps (if your linking existing data) are important tools in this process, much like SOQL, its bad news to do DML in loops, as you only get 150 DML operations per request before the governors blow. So we must index and list items within the various loops to ensure we are following best practice for bulkificaiton of DML as well.  If your using ExternalId fields, you can avoid some of this, but to much use of those comes at a cost as well, and your not always able to add these to all objects, so traditionally the above is pretty much the most bulkified way of inserting Opportunities.

Same again, but with a Unit Of Work…

Now thats take a look at the same sample using the Unit Of Work approach to capture the work and commit it all to the database in one operation. In this example notice first of all its a lot smaller and hopefully easier to see what the core purpose of the logic is. Most notable is that there are no maps at all, and also no direct DML operations, such as insert. 

img_strategy_targetInstead the code registers the need for an insert with the unit of work, for it to perform later via the registerNew methods on lines 8,13,19 and 24. The unit of work is keeping track of the lists of objects and is also providing a kind of ‘stitching’ service for the code, see lines 19, 23 and 24. Because it is given a list of object types when its constructed (via MY_SOBJECT) and these are in dependency order, it knows to insert records its given in that order and then follow up populating the indicated relationship fields as it goes. The result I think is both making the code more readable and focused on the task at hand.


			SObjectUnitOfWork uow = new SObjectUnitOfWork(MY_SOBJECTS);
			for(Integer o=0; o<10; o++)
			{
				Opportunity opp = new Opportunity();
				opp.Name = 'UoW Test Name ' + o;
				opp.StageName = 'Open';
				opp.CloseDate = System.today();
				uow.registerNew(opp);
				for(Integer i=0; i<o+1; i++)
				{
					Product2 product = new Product2();
					product.Name = opp.Name + ' : Product : ' + i;
					uow.registerNew(product);
					PricebookEntry pbe = new PricebookEntry();
					pbe.UnitPrice = 10;
					pbe.IsActive = true;
					pbe.UseStandardPrice = false;
					pbe.Pricebook2Id = pb.Id;
					uow.registerNew(pbe, PricebookEntry.Product2Id, product);
					OpportunityLineItem oppLineItem = new OpportunityLineItem();
					oppLineItem.Quantity = 1;
					oppLineItem.TotalPrice = 10;
					uow.registerRelationship(oppLineItem, OpportunityLineItem.PricebookEntryId, pbe);
					uow.registerNew(oppLineItem, OpportunityLineItem.OpportunityId, opp);
				}
			}
			uow.commitWork();

The MY_SOBJECT variable is setup as follows, typically you would probably just have one of these for your whole app.

	// SObjects (in order of dependency)
	private static List MY_SOBJECTS =
		new Schema.SObjectType[] {
			Product2.SObjectType,
			PricebookEntry.SObjectType,
			Opportunity.SObjectType,
			OpportunityLineItem.SObjectType };

Looking into the Future with registerNew and registerRelationship methods

Screen Shot 2013-06-09 at 15.06.11These two methods on the SObjectUnitOfWork class allow you to see into the future. By allowing you to register relationships without knowing the Id’s of records your inserting (also via the unit of work). As you can see in the above example, its a matter of providing the relationship field and the related record. Even if the related record does not yet have an Id, by the time the unit of work has completed inserting dependent records for you, it will. At this point, it will set the Id on the indicated field for you, before inserting the record.

Delegating this type of logic to the unit of work, avoids you having to manage lists and maps to associate related records together and thus keeps the focus on the core goal of the logic.

Note: If you have some cyclic dependencies in your schema, you will have to either use two separate unit of work instances or simply handle this directly using DML.

Deleting and Updating Records with a Unit Of Work…

This next example shows how the unit of work can be used in a editing scenario, suppose that some logic has taken a bunch of OpportunityLineItem’s and grouped them. You need to delete the line items no longer required, insert the new grouped line and also update the Opportunity to indicate the process has taken place.

			// Consolidate Products on the Opportunities
			SObjectUnitOfWork uow = new SObjectUnitOfWork(MY_SOBJECTS);
			for(Opportunity opportunity : opportunities)
			{
				// Group the lines
				Map<Id, List> linesByGroup = new Map<Id, List>();
				// Grouping logic
				// ...
				// For groups with more than one 1 line, delete those lines and create a new consolidated one
				for(List linesForGroup : linesByGroup.values() )
				{
					// More than one line with this product?
					if(linesForGroup.size()>1)
					{
						// Delete the duplicate product lines and caculate new quantity total
						Decimal consolidatedQuantity = 0;
						for(OpportunityLineItem lineForProduct : linesForGroup)
						{
							consolidatedQuantity += lineForProduct.Quantity;
							uow.registerDeleted(lineForProduct);
						}
						// Create new consolidated line
						OpportunityLineItem consolidatedLine = new OpportunityLineItem();
						consolidatedLine.Quantity = consolidatedQuantity;
						consolidatedLine.UnitPrice = linesForGroup[0].UnitPrice;
						consolidatedLine.PricebookEntryId = linesForGroup[0].PricebookEntry.Id;
						uow.registerNew(consolidatedLine, OpportunityLineItem.OpportunityId, opportunity);
						// Note the last consolidation date
						opportunity.Description = 'Consolidated on ' + System.today();
						uow.registerDirty(opportunity);
					}
				}
			}
			uow.commitWork();

Transaction management and the commitWork method

Database transactions is something you rarely have to concern yourself within Apex…. or do you? Consider the sample code below, in it there is a deliberate bug (line 22). When the user presses the button associated with this controller method, the error occurs, is caught and is displayed to the user via the apex:pagemessages component. If the developer did not do this, the error would be unhandled and the standard Salesforce white page with the error text displayed would be shown to the user, hardly a great user experience.

	public PageReference doSomeWork()
	{
		try
		{
			Opportunity opp = new Opportunity();
			opp.Name = 'My New Opportunity';
			opp.StageName = 'Open';
			opp.CloseDate = System.today();
			insert opp;
			Product2 product = new Product2();
			product.Name = 'My New Product';
			insert product;
			// Insert pricebook
			PricebookEntry pbe = new PricebookEntry();
			pbe.UnitPrice = 10;
			pbe.IsActive = true;
			pbe.UseStandardPrice = false;
			pbe.Pricebook2Id = [select Id from Pricebook2 where IsStandard = true].Id;
			pbe.Product2Id = product.Id;
			insert pbe;
			// Fake an error
			Integer x = 42 / 0;
			// Insert opportunity lines...
			OpportunityLineItem oppLineItem = new OpportunityLineItem();
			oppLineItem.Quantity = 1;
			oppLineItem.TotalPrice = 10;
			oppLineItem.PricebookEntryId = pbe.Id;
			insert oppLineItem;
		}
		catch (Exception e)
		{
			ApexPages.addMessages(e);
		}
		return null;
	}

However using try/catch circumvents the standard Apex transaction rollback during error conditions. “Only when all the Apex code has finished running and the Visualforce page has finished running, are the changes committed to the database. If the request does not complete successfully, all database changes are rolled back.”. Therefore catching the exception results in the request to complete successfully, thus the Apex runtime commits records that lead up to the error occurring. This results in the above code leaving an Opportunity with no lines on the database.

The solution to this problem, is to utilise a Savepoint, as described in the standard Salesforce documentation. To avoid the developer having to remember this, the SObjectUnitOfWork commitWork method creates a Savepoint and manages the rollback to it, should any errors occur. After doing so, it throws again the error so that the caller can perform its own error handling and reporting. This gives a consistant behaviour to database updates regardless of how errors are handled by the controlling logic.

Note: Regardless of using the commitWork method or manually coding your Savepoint logic, review the statement from the Salesforce documentation regarding Id’s.

Summary

As you can see between the two samples in this blog, there is significant reduction of over half the source lines when using the unit of work. Of course the SObjectUnitOfWork class does have its own processing to perform. Because it is a generic library, its never going to be as optimum as if you would write this code by hand specifically for the use case needed as per the first example.

perfect-balance

When writing Apex code, optimisation of statements is a consideration (consider Batch Apex in large volumes). However so are other things such as queries, database manipulation and balancing overall code complexity, since smaller and simpler code bases generally contains less bugs. Ultimately, using any utility class, needs to be considered on balance with a number of things and not just in isolation of one concern. Hopefully you now have enough information to decide for yourself if the benefit is worth it in respect to the complexity of the code your writing.

Unit Of Work is a Enterprise Application Architecture pattern by Martin Fowler.


Leave a comment

Savings on Dreamforce 2013 Admission!

As a Force.com MVP I’ve been given a special discount code D13MVPREF for Dreamforce 2013 to pass on. Feel free to pass it around as well, there is no limit to how often it can be used to save  money on your entry to this amazing event!

Dreamforce.001

If your on the fence about Dreamforce 2013, I recommend it 110%, its a huge event and unlike smaller events, the educational cost benefit is very high. Since there are many many developer tracks, code review activities and training sessions.

There is so much content in fact, that an argument could be made that the more people you send the more benefit you get! Also there are many opportunities to discuss with fellow developers and Salesforce employees. In fact you’ll be hard pushed to attend the whole event without bumping shoulders with a Salesforce Product Manager!

If you need any more convincing head over to the official Dreamforce 2013 site!