Apex Code Enhancements and Collections best practices

by Quinton Wall on January 29, 2010 at 03:45 PM

Spring '10 is just around the corner, with many great new features. One of the Apex Code enhancements which caught my attention was the limits on the number of items a collection can hold has been removed. The previous limit was set at 1000. Add this to the new ability to use generic sObjects to create a collection and Collections within the platform just got a whole lot more powerful.

As Ben Parker, the o-so-wise uncle of Peter Parker (aka Spiderman) once said: "with great power comes great responsibility." Changes to Collections is no different, and require some new thinking in regards to best practices.

The release notes, for example, mention that there is still a limit on heap size so care must be taken to not load up a collection and hit this limit. Good news is that a few other other Spring '10 changes can certainly be used to ensure you design your applications as efficiently as possible. 

Here are just a few new SOQL clauses and functions which can be used with collections to help make the most fo the changes.

This is certainly not a complete list, but should certainly be something every developer is familiar with.

Action Chaining in Visualforce

by Dave Carroll on September 10, 2009 at 03:45 PM

Action chaining is a technique to handle the infamous "MIXED_DML_OPERATION, DML operation on setup object is not permitted Error" problem.

You may not know it but there are two types of objects that you can interact with on the platform. One is "setup" object and the other is a "non-setup" object. A "setup" object is one that must be edited from the setup or builder area of the platform. These object include the User object, Ogranization object, Email templates and so on.

See this article for details DML operations of a non-setup sObject and a setup sObject

Read the full article and check out the source code at Visualforce Action Chaining

See you at Dreamforce!!

Dave Carroll

Catching up on Tech Talks: Database and Force.com Sites

by Jon Mountjoy on June 24, 2009 at 04:25 AM

We recently held two great Tech Talks. If you missed them and want to catch up, then click through:

Enjoy!

Partner Tech Talk: What's Next for Force.com? A Peek into the Platform's Future.

by Jon Mountjoy on June 10, 2009 at 06:29 AM

44E41846-B312-44E9-901D-BA03E50FE2A8.jpg

Interested in learning more about what's to come in future releases of the Force.com platform so that you can plan ahead? Then join David Brooks, VP of Product Management, Platform for a webinar session that will cover major initiatives we have planned and the enhancements that lie ahead for the platform, particularly in the areas of:

  • Customization and Schema
  • Programmable User Interface
  • Workflow and Cloud Logic
  • Administration and Sharing
  • Packaging and Upgrades

When: Wednesday, June 17, 2009
Time: 10 AM PDT

Register here.

Upcoming Tech Talk: Introduction to the Force.com Database

by Andrew Albert on May 26, 2009 at 03:59 PM

New to Force.com? Want to learn more about the Force.com Database and learn how easy it is to create a custom data model on Force.com? What about learning how to enable triggers, data validations, and field history, and more? If so, please join us on Wednesday, June 3rd, 10 am PDT for the next session in our tech talk series, Introduction to the Force.com Database.

Topics Include:

  • Learn how to create database objects to persist data
  • Discover how a rich user interface is automatically generate
  • See how to use triggers, validation and field history
  • Learn a little about the data security and sharing features

Please register for the upcoming Webinar here.

If interested in checking out archived Tech Talks, please check out these links:

Are You Having Problems Sharing?

by Jesse Lorenz on May 14, 2009 at 12:01 PM

The number one rule in life for author Robert Fulghum is to "Share everything."  Your Force.com application is one place where it’s okay to break that rule and not share everything. That’s why Force.com allows developers and administrators to control access to data at many different levels. You can control access at the object-level, the record-level and even at the field-level. In the vast majority of cases, the appropriate Force.com sharing settings can be defined declaratively by simply pointing and clicking. In some cases, developers may need the ability to define even more sophisticated sharing settings, and this is where Apex Managed Sharing comes in.

Apex Managed Sharing allows you to use Apex Code to build sophisticated and dynamic sharing settings that aren’t otherwise possible. For example, a developer can use Apex Managed Sharing to write a trigger that will automatically share a custom object record with a user that has been specified in a lookup field. You can also use Apex Managed Sharing to write custom Visualforce controllers that implement your sharing logic.

After an introduction to sharing, the accompanying article looks at the components of Apex Managed Sharing, and how you can use Apex Managed Sharing in your own applications. The article, Using Apex Managed Sharing to Create Custom Record Sharing Logic, also provides sample code for the trigger described above.

Navigating Relationships.....

by Nick Simha on February 7, 2009 at 08:38 AM

Navigating relationships in life may be hard but doesn't have to between custom sObjects :). The SOQL documentation  has several examples with standard sObjects. Custom sObjects have some differences - mostly syntactical.  We will illustrate that using a few sample SOQL queries.

We will use the example from the Developer Guide The object model is reproduced below (click on the pictures to enlarge them).

M1When you insert a relationship field on an sObject (either a lookup or master-detail) to another object, the other object is called the parent sObject.  So Location is the parent of Position in the object model shown.  The cardinality from parent to child is one to many, so a single location can have many positions associated with it.  The child object will have both the ID of the related parent record as well as a relationship field to access the fields in the related record.  


CHILD to PARENT

Say we want to find the location id and city associated with a given position.  The query would look like this

SELECT Location__r.Id, Location__r.City__c FROM Position__c p WHERE p.Name='POS-00001'

What is Location__r?  It is the name of the relationship field from Position to Location.  You can find this on the field definition screen - click on the picture on the left.  Note that you have to append a __r to the name on the screen. You can traverse multiple levels of child parent relationship in this manner.  For example, we can retrieve the field values of a location record from Job Application by traversing from Job Application to  Position to Location as shown below.M2

SELECT Position__r.Location__r.Id, Position__r.Location__r.City__c  FROM Job_Application__c ja WHERE ja.Name = 'JA-00001'



PARENT to CHILD

Remember that the cardinality of this relationship is one to many so we should expect to retrieve back a collection of child objects.  The child objects are retrieved using a sub-query.

Location__c[] locations = [SELECT  l.Name, l.City__c, (SELECT Name, Department__c FROM Positions__r) FROM Location__c l ]

Positions__r is the name of the child relationship.  We find it on the field definition screen as before - click on the picture to the right.  Notice the plural (by default) and appending __r (as before).  Now we can iterate over the collection of locations as well as the associated child positions for each location in a loop.

for( Location__c l : locations ){
 // position object associated with each location
for( Position__c p : l.positions__r){
System.debug('*****>>>>>> Name = ' +p.Name +' Department = ' +p.Department__c ) ;
}
} M3

The previous query did an outer join, so it would retrieve locations even if there were no associated positions. To only retrieve locations for which there are associated positions, we would need to do a semi-join as shown below.

Location__c[] locations = [SELECT Id, Name, City__c, (SELECT Id, Name, Department__c FROM Positions__r) FROM Location__c WHERE Id IN (SELECT Location__c from Position__c) ] ;

CHANGING THE ASSOCIATED RECORD 

Notice the query after IN in the previous example. Location__c contains the ID of the related Location record.

We can use this field to change the related record as in the example below.


// Retrieve a position record with the ID of the associated location record
Position__c p = [SELECT Location__c, Location__r.Name FROM Position__c
                WHERE Location__r.Name='HQ' LIMIT 1]
// Retrieve the Id of the record we want to point it to
Location__c loc = [ select Id from Location__c where Name='Reston' ] ;
//change it and update the database
p.location__c = loc.Id ;
update p ;

The position now points to the Reston location.





Unlearning the Database and Logic Tier Integration

by Ryan Marples on November 20, 2008 at 08:47 AM

One of the things about transitioning from traditional web development to developing in the cloud is that you tend to need to “unlearn” as much stuff as you need to learn. One of those first things I had to unlearn was the work required to talk between the database tier and the application server tier. Most applications these days are very data-intensive, yet there’s this thick line that gets drawn between the database and the rest of the application. The database is modeled around tables and columns whereas the application logic is modeled around objects and properties. Results from the database are a collection of flat rows, but results from application logic are objects held together by sequential and hierarchical references to each other. Modifying an application object’s data is done by setting a property, whereas modifying a database row involves creating and issuing a text-based command (i.e. UPDATE statement) sent to the database. And so an entire category of techniques and technologies was born to solve the translation problem between the database tier and the application tier. Writing these mapping layers is neither fun nor particularly value-added. Many progressive developers are now using automatic code-generation to spit out thousands of lines of code, but almost always need to get in there and mess with what’s been generated. Not to mention writing a bunch of boring code to efficiently handle database connections.

Now let’s talk about how Force.com handles this. Internal to the Force.com architecture is a database and application server that is subject to all the same issues. However, specific extensions have been made to the application server to handle much of this low-level logic and present you, the developer, with a higher-level, richer way to interact with the database. I want to highlight a few key features around this:

Database Connections
You don’t need to (and in fact, you aren’t able to) create a connection to the database server. Instead when you want to issue a query, the application server will handle the connection internally on your behalf. No connection objects, no server names, usernames and passwords, no worrying about disconnecting.

Object/Relational Mapping
When you execute a query to the Customer table, you don’t get back a “recordset”, you get back a strongly-typed Customer object. Even field types are preserved: if that table has a CreatedDate column defined with a date data type, then your Customer object will have a property called CreatedDate with a date data type. The ability to just run a query and get back an array of application objects is a huge jump in productivity.

Inserts, Updates, and Deletes
While you do use a SQL-like expression (SOQL) to retrieve data from the database, you do not (and actually are not able to) run INSERT, UPDATE, and DELETE SQL statements. Instead, the Apex language has been extended to natively support database operations. To insert a record, you simply create an instance of your strongly-typed object, set it’s properties and say “insert myObject;”. No more concatenating brittle strings to form an INSERT SQL statement. Not only does this save you so much time, it greatly improves the readability of your code.

These items above are just a few of the relevant features, I’d encourage you to explore more on your own. Check out the Database Integration section of Jon’s Introduction to Apex article to see some code examples of this stuff in action.

At the end of the day, unless you feel that you have some true intellectual property in the way you connect to, map to, and integrate with your database today, why would you want to write all this infrastructure yourself? Force.com enables you get right to the core business logic of your application.

Happy "unlearning".

An Introduction to the Force.com Database

by Jon Mountjoy on October 22, 2008 at 04:59 AM

Data persistence lies at the heart of many of your applications. At the end of the day, you often want to store data, and interact with that data. The Force.com platform provides a powerful and intuitive data persistence layer in the cloud, which I've been researching and writing up over the past few weeks. I think it has a load of interesting features such as:

  • A metadata driven approach to automatically generating powerful user interfaces for all of your persisted data objects (if you want).
  • A web service that lets you modify, create, introspect and search database objects - with a bunch of tools built around the service to get your data into the cloud
  • A great integration with the Apex language, making it very easy for you to programatically interact with the database if you need to.
  • A neat paradigm of defining relationships between objects (tables) instead of working with foreign keys and such like.
  • An interesting formula language that you can use to have fields in your persisted objects automatically derive values from calculations on other fields.
  • Fully fledged reporting, straight out of the box.
  • A vast array of data security and sharing option.
  • And a lot more...

So, check out the article: An Introduction to the Force.com Database!

Comments appreciated!

Workbench: From Idea to 2.0

by Ryan Brainard on July 1, 2008 at 09:57 PM

Wb2_ssoAbout a year ago, I started learning PHP and was just getting my feet wet with the Force.com API, and I soon realized what I would need to do to really learn both --  build a web-based version of Apex Data Loader. I had used the Data Loader to import and extract data, and it did this pretty well, but thinking how cool it would be if this could all be done directly in a web browser like the rest of the Salesforce on-demand applications, I was very excited to start this project.

It started with downloading the open source PHP Toolkit and understanding how to make basic connections and calls to the Force.com API, and this quickly progressed into building out all the major functions of the Data Loader completely in PHP. Being my first major project in PHP, it was still had its fair share of not-so-good practices, but as a testament to the simplicity of both PHP and the Force.com API, the DataLoader.PHP (as the Workbench was once known) became reality. Building on this foundation, more and more features were added and the existing code was refactored to be more efficient and extensible. Soon I realized that I had something that could do much more than the Data Loader with the new Describe, Undelete, and Purge functions and plans to implement a whole suite of useful tools for Salesforce administrators and developers, the application was renamed the Workbench and version 1.0 was released as an open source project on Google Code.

With a modest number of downloads and feedback from the open source community, the feature requests started to roll in for the next generation of the Workbench. Back at the drawing board, I implemented a SOSL Search function, added new Smart Lookup capabilities, built an extensible configuration framework, and tuned the overall performance. All of this was packaged in a new, clean user interface and delivered as Workbench 2.0 just in time for the Salesforce Summer '08 release.

For more information and to download Workbench 2.0 or its source code, visit the project page on developer.force.com.