Posts Tagged ‘java’
.png)
At long last, the oft-rumored VMForce has been officially announced.
Huh?
VMForce is a technology brought about by a partnership between salesforce.com and VMware, the leader in virtualization technology. VMForce enables Java applications to run on Force.com infrastructure, the robust development platform built by the folks at salesforce.com.
What does all of that mean?
Java is one of the most widely used development languages in the world. It is a mature technology with millions of active developers, with more applications running than can likely be counted. With VMForce, many of those applications can now be migrated easily to run in the cloud.
These applications will then be available anywhere, on almost any device. They are instantly social, searchable, and scalable. And since they’re on Force.com, you get great security and visibility into uptime.
Had an interesting challenge the other day: all the best last data migration plans were failing. Why? The tool of choice — which one is not important — failed. What to do?
I used Cloud Converter. Quelle surprise, right? I could have used something else, but it’s some decent code that I’m familiar with — so I used it. How?
I first did a test to be sure the API was working using a SalesforceSession object. Why test? Well, you never know. Why the Cloud Converter provided "SalesforceSession"? It’s easy. One line of code or so with a valid user and I established that the user was good, that the API was functional and that the user had rights to the API.
Sweet!
Then I moved to the source documents. I had two kinds: Simple CSV’s and Complex CSV’s.
Simple CSV’s were easy. I added a standard Java FileReader to the sample code, pointed it at the file, and split the data into component parts. Then I built a collection of "Sproxy" objects, added the SalesforceSession to a SalesforceDAO and executed an upsert. Start to finish, about 5 minutes for the first file.
Complex CSV’s were tougher. The difference between simple and complex was that the data contained commas. I know, this seems like it should be relatively easy, but at the time I was drawing a blank. So I imported those Complex CSV’s into Excel, saved them as Excel files and then used another Cloud Converter class, ExcelConverterService.
ExcelConverterService reads an XLS and breaks the data in the cells into a collection of type safe objects. Then I did the same thing I had done with Simple CSV’s: iterated through the data, added it to a Sproxy collection and threw it at the API.
Eh voila – instant data load.
Truth be told, I would rather not have had to do it this way. But when all else failed, it was nice to have an extra tool in my kit.
You can find Cloud Converter over on Google Code or on Developer.Force.com.
You can follow Reid Carlberg on Twitter or email him at rcarlberg@modelmetrics.com.
One of the absolute best features of the Salesforce.com/Force.com API is the ability to handle lookup relationships gracefully using external IDs. You can easily have one object with an external ID and then add another object with a lookup relationship to the first without having to know the ID Salesforce.com assigned it. You’ve probably seen this in action in the Apex Data Loader. It saves a huge amount of time.*
I recently had to implement this on my own outside of an existing tool. I had a hard time finding any useful documentation in this area. This write up aims to fill that gap.
Let me start by describing the objects we’re working with. I’m using custom objects, but this can work with standard objects as well. Let’s call them ObjectA and ObjectB. ObjectB has a one-to-many relationship with ObjectA. ObjectA has an external ID field (unique, case insensitive) called “ExternalIdOnObjectA”. ObjectB as a lookup field to ObjectA. The table for ObjectA is populated. We’re upserting a group of ObjectB.
The goal is to create something that says, in effect, “when adding this ObjectB, determine the value to store in the field LookupToObjectAFromObjectB using this value, which you can lookup on ObjectA using the field ExternalIdOnObjectA.” The XML looks something like this:
<…other fields…>
<LookupToObjectAOnObjectB__r>
<type xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">ObjectA__c</type>
<Id xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:nil="true" xsi:type="xsd:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
<ExternalIdOnObjectA__c>CC001</ ExternalIdOnObjectA __c>
</ LookupToObjectAOnObjectB __r>
<…other fields…>
A couple of things worth noting:
* The field on ObjectB we’re calling out is the “__r” version and not the “__c”. If you knew the Salesforce.com ID, you would set it to the “__c” version and be done.
* Note the content of the LookupToObjectAOnObjectB tag includes standard information you would see as part of a regular SObject: Type, indicating that it goes to ObjectA, and ID which in this case is empty since we don’t know it.
* Before closing, we define the ExternalIdOnObjectA field value.
That’s it. So how do we do this in Java? Setting a field value in Java is normally just a matter of adding a MessageElement to the SObject.
MessageElementBuilder.getMessageElement(FieldName, FieldValue)
And this is no different. By the way, “MessageElementBuilder” here is just a little utility class I have that handles – wait for it – building message elements. It’s the same kind of thing you see in the sample code from
By now you’ve probably figured out where we’re going. The next step is to build an SObject for the reference first and then set that SObject as the FieldValue for the message element.
SObject foreignKeyToResolve = new SObject();
ret.setType(“ObjectA__c”);
ret.set_any(new MessageElement[] {
MessageElementBuilder.getMessageElement
("ExternalIdOnObjectA__c", "CC001") });
SObject objectBInstance = new SObject();
ret.setType(“ObjectB__c”);
ret.set_any(new MessageElement[] {
MessageElementBuilder.getMessageElement
("LookupToObjectAOnObjectB__r", foreignKeyToResolve) });
And that’s all there is to it. Hopefully this saves you some time down the road. FWIW, I was working in Java on the Cloud Converter when I wrote this. However, you should be able to use this technique with any of the toolkits — .NET, PHP, etc.
Good luck!
* In fact, upsert with foreign key resolution saves so much time that I’ve refused to use integration toolkits that don’t support it out of the box. The good news is that the two major vendors who I have had the joy of talking with about this issue have responded quickly.
(????
I just posted Cloud Converter to Google code. It’s a bunch of Java code that:
** connects to a dirt bound database you specify — anything with a JDBC connector should work (MySQL, Lotus Notes, Microsoft SQL, Oracle)
** inspects the meta data
** creates a matching object in Force.com
** modifies the default page layout to include all of the fields and creates a custom tab for it
** moves data from the dirt to the cloud
Pretty straightforward. The "ReadMe.txt" gives more detail. I’ll be putting together a screen flow shortly. Questions? Drop me an email: rcarlberg@modelmetrics.com.
Model Metrics has released this as open source with an MIT License.
Enjoy!
1/7 Update: This is now on Salesforce.com’s Code Share.