Thursday, October 24, 2013

What are the defined fields for each salesforce object

In salesforce(www.salesforce.com) there are many objects like accounts, users, leads...Etc. When using REST API or when executing a SOQL we need to give the exact name of the field.
Since salesforce does not support SELECT * from XXXX

This is way I used to extract necessary information from salesforce

1. Login to salesforce
2. Go to Setup->Develop API
3. Generate Partner WSDL (If you working with sandbox environment it might gives some errors but partner WSDL is sufficient)
4. Generate stub jar file Ref :http://www.salesforce.com/us/developer/docs/api_asynch/Content/asynch_api_code_set_up_client.htm
5. Use the following code sample

       ConnectorConfig sfconfig = new ConnectorConfig();
        sfconfig.setUsername("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        sfconfig.setPassword("xxxxxxxxxxxxxxxxxxxxxxQNx26Lb4PTw");        
        PartnerConnection  connection = Connector.newConnection(sfconfig);
         DescribeSObjectResult[] describeSObjectResults =  connection.describeSObjects(
                   new String[] { "account"});
        for (int i=0;i < describeSObjectResults.length; i++)
        {
            DescribeSObjectResult desObj = describeSObjectResults[i];
            String objectName = desObj.getName();
            com.sforce.soap.partner.Field[] fields = desObj.getFields();
            if (desObj.getActivateable()) System.out.println("\tActivateable");
            for(int j=0;j < fields.length; j++)       {                        
                com.sforce.soap.partner.Field field = fields[j];
                System.out.println("\tField: " + field.getName());
                System.out.println("\t\tLabel: " + field.getLabel());
                if (field.isCustom()) 
                    System.out.println("\t\tThis is a custom field.");
                System.out.println("\t\tType: " + field.getType());
                if (field.getLength() > 0)
                    System.out.println("\t\tLength: " + field.getLength());
                if (field.getPrecision() > 0)
                    System.out.println("\t\tPrecision: " + field.getPrecision());
                if (field.getType() == FieldType.picklist)
                {                            
                  
                    PicklistEntry[] picklistValues = field.getPicklistValues();
                    if (picklistValues != null && picklistValues[0] != null)
                    {
                        System.out.println("\t\tPicklist values = ");
                        for (int k = 0; k < picklistValues.length; k++)
                        {
                            System.out.println("\t\t\tItem: " + picklistValues[k].getLabel());
                        }
                    }
                }
                if (field.getType() == FieldType.reference)
                {                            
                   
                    String[] referenceTos = field.getReferenceTo();
                    if (referenceTos != null && referenceTos[0] != null)
                    {
                        System.out.println("\t\tField references the following objects:");
                        for (int k = 0; k < referenceTos.length; k++)
                        {
                            System.out.println("\t\t\t" + referenceTos[k]);
                        }
                    }
                }
            }            
        }

Wednesday, October 16, 2013

Creating a new remote access application in Salesforce

Create OAuth Token and secret from Salesforce


If your planning to get Sales force information from REST API you will find that creating Remote Access app by following http://wiki.developerforce.com/page/Getting_Started_with_the_Force.com_REST_API is not working as describe

Here how it goes

Log in to Salesforce.com with your developer account, navigate to Setup ➤ Develop ➤ Remote Access, 
and click New to create a new remote access application if you have not already done so.

This is not working under the new Salesforce changes

Once you click Remote Access it will say 

Remote Access Objects have been moved to Applications. You'll be redirected to that page in five seconds, or you can click Take Me There to go now. 

Then you will be forword to Create -> Apps section

Go to Connected Apps and create new



Once you save this you can get the OAuth token and secret

Saturday, October 12, 2013

Read and process large one line JSON file

My initial problem was to read and process large one line JSON file. with traditional approaches it took 3 hours to read and process the JSON file. So I have done research in this area and found a way to read the JSON file chunk by chunk, now I can do the same thing in 5 min

Bellow I have break the JSON which had 200000 elements in to 20 * 10000 chunks

public static void jsonFileReader() throws JsonParseException, IOException{
JsonFactory f = new MappingJsonFactory();
JsonParser jp = f.createJsonParser(new File("MyHugeJSonFile.json"));
JsonToken current;

current = jp.nextToken();
if (current != JsonToken.START_OBJECT) {
System.out.println("Error: root should be object: quiting.");
return;
}
int i = 0;
while (jp.nextToken() != JsonToken.END_OBJECT) {

String fieldName = jp.getCurrentName();
current = jp.nextToken();
if (fieldName.equals("employees")) {

if (current == JsonToken.START_ARRAY) {
List<String> strings = new ArrayList<String>();
String previousValue = "";
while (jp.nextToken() != JsonToken.END_ARRAY) {
JsonNode node = jp.readValueAsTree();
String valueAsText = node.get("id").getTextValue();
strings.add(valueAsText);
if((strings.size() == 100)) {
String valueAsText1 = null;
while (jp.nextToken() != JsonToken.END_ARRAY) {
JsonNode node1 = jp.readValueAsTree();
valueAsText1 = node1.get("id").getTextValue();
if(!previousValue.equals(valueAsText1)) {
break;
} else {
strings.add(valueAsText1);
}
}
int j =0;
for (Iterator<String> iterator  = strings.iterator(); iterator.hasNext();) {
i = i + 1;
j = j + 1;
String string = (String) iterator .next();
System.out.println(i+" -- "+j+" --> "+string);
strings = new ArrayList<String>();
}
System.out.println("-------------------------------------------------------------");
strings.add(valueAsText1);
}
previousValue = valueAsText;
}
int j =0;
for (Iterator<String> iterator  = strings.iterator(); iterator.hasNext();) {
i = i + 1;
j = j + 1;
String string = (String) iterator .next();
System.out.println(i+" -- "+j+" --> "+string);
strings = new ArrayList<String>();
}
System.out.println("-------------------------------------------------------------");

} else {
System.out.println("Error: records should be an array: skipping.");
jp.skipChildren();
}
} else {
System.out.println("Unprocessed property: " + fieldName);
jp.skipChildren();
}
}

System.out.println("Total Record size " + i);
}

Sunday, October 6, 2013

Insert large data sets with Hibernate

Hibernate is a generic ORM framework and when it comes to very specific scenarios you may face difficulties. Specially when try to insert/write large data set(more than 1 million records) to the database at once.

But there are ways to get away from that

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

int i = 0;
for (Iterator<T> iterator = persistenceObject.iterator(); iterator.hasNext();) {
  i++;
  session.saveOrUpdate(iterator.next());
  if (i % 50 == 0) {
session.flush();
session.clear();
  }
}
tx.commit();

session.close();


Above example write 50 records at once not 1 million at once. If you have more efficient ways please comment on this