+ Start a Discussion
ganeshganesh 

How to select all fields from SObject thro SOQL?

Hi All,

I need to select all the fields ( like accountName, accountNumber etc ) of Account ( or any sobject ) through SOQL.

I constructed the select qurey as follows.

DescribeSObjectResult res = binding.describeSObject( "Account" );
Field[] fields = res.getFields();
String expr = "";
for( int i=0; i < fields.length-1; i++ )
{
expr += fields[i].getName() + ", ";
}
expr += fields[ fields.length - 1 ].getName();

String qry = "Select " + expr + " from Account";
QueryResult res = binding.query( qry );

While executing this, I am getting following exception.

Is there any easier way to achieve this!

Kindly help me solve this problem!

Regards,
Ganesh Kumar N.S.A

Exception in thread "main" java.rmi.UnmarshalException: Error unmarshaling return; nested exception is:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.apache.crimson.tree.ElementNode2
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:217)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source)
at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:135)
at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:96)
at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
at com.adventnet.authentication.interceptor.ClientPrincipalAssociator.invoke(ClientPrincipalAssociator.java:52)
at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
at $Proxy1.importFromSForce(Unknown Source)
at com.adventnet.examples.ImportUtilClient.main(ImportUtilClient.java:39)
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.apache.crimson.tree.ElementNode2
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1278)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1603)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1271)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:215)
... 10 more
Caused by: java.io.NotSerializableException: org.apache.crimson.tree.ElementNode2
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1054)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1224)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1050)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1332)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:367)
at java.util.Vector.writeObject(Vector.java:1017)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
DevAngelDevAngel

Hi ganesh,

Looks like the error is on the client side serializer.  First, though, there is no select * syntax available.  You are approaching the problem correctly by creating a comma delimeted list of fields from the describe call.

I would put a debug statement to print the entire SOQL statement.  Then examine it closely to make sure that it is correct.  (I'm fairly confident that you statement is well formed based on your code snippet.)

I would also like to know which soap stack you are using and find out if there are any string length limitiations being imposed.  It may be that the length of the SOQL statement is causing the soap stack to gack.  (seems silly, but could happen).  Try doing half the fields and see if you get the same exceptions.

If you have the option, I would use Axis 1.1 libs.

Cheers

DrawloopSupportDrawloopSupport
Any updates on the "SELECT * FROM..." syntax? This would be a very helpful feature.
SuperfellSuperfell
No, you still need to explictly indicate which fields to want to query.
OriPriceOriPrice

Could be useful if you promote this idea (if you haven't done it yet):

 

http://ideas.salesforce.com/article/show/70004?page=last#lastPost

Ezio_2010Ezio_2010

Alo again.... Im in the same, just saw solution, Ill do it then...but, tell me why there's no select * from... just to keep my peace of mind.

 

thank u

Kyle RobertsKyle Roberts

This is utterly ridiculous, select * should have been implemented day one.

Kyle RobertsKyle Roberts

Abused or not, governors are enough pain/limitation considering the costs to build a platform on force.com

 

 

Edwin VijayEdwin Vijay

Maybe, i am posting a reply here after a long time. Anyhow, wanted to share the reason i think why "select *" is not available..

 

As far as i know each Sobject(Account,Contact etc) is not a actual database table. Each table that you actually query using SOQL is actually a VIEW of the master table..  So, basically one MASTER TABLE and many VIEWS (each per org per Sobject)..

 

Dat's the reason you cannot have a Select *. I dont know if there is a way to overcome this even if Salesforce likes to.

John CasimiroJohn Casimiro

I posted a workaround for this on my blog using Apex. Perhaps something similar can be done in Java.  The method involves using the Schema.getGlobalDescribe() method to get fields on an object and then dynmically generate a query string with all the fields.

 

Hope this is helpful,

http://johncasimiro.com/mimic-a-sql-select-statement-in-soql-using-ap

Red2678Red2678

Do you still have this posted somwhere? The link is dead. Thanks!

 

~Red

John CasimiroJohn Casimiro
Here is the code snippet, https://gist.github.com/734428
ppraveenm1.3934966058905745E12ppraveenm1.3934966058905745E12
Hi I hope this will help.

/*
* @description: A code snippet that mimics the popular Select * SQL syntax in force.com's Apex language.
*/

// Initialize setup variables
String objectName = 'Contact';  // modify as needed
String query = 'SELECT';
Map<String, Schema.SObjectField> objectFields = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap();

// Grab the fields from the describe method and append them to the queryString one by one.
for(String s : objectFields.keySet()) {
   query += ' ' + s + ', ';
}

// Manually add related object's fields that are needed.
query += 'Account.Name,'; // modify as needed

// Strip off the last comma if it exists.
if (query.subString(query.Length()-1,query.Length()) == ','){
    query = query.subString(0,query.Length()-1);
}

// Add FROM statement
query += ' FROM ' + objectName;

// Add on a WHERE/ORDER/LIMIT statement as needed
query += ' WHERE firstName = \'test\''; // modify as needed
 
try {
        List<Contact> contacts = database.query(query);
} catch (QueryException e){
        //perform exception handling
}
praveen murugesanpraveen murugesan
Hi Ganesh,

To achive this you can use like this

DescribeSObjectResult res = binding.describeSObject( "Account" );
Field[] fields = res.getFields();
String expr = "";
for( int i=0; i < fields.length-1; i++ )
{
expr += fields[i].getName() + ", ";
}
expr += fields[ fields.length - 1 ].getName();

String qry = "Select " + expr + " from Account";

QueryResult res = binding.query( qry );

For the second question

You cant do in direct way. As Ramu's saidf you should use  dynamic query.

Thanks,

Praveen Murugesan
Vikrant ShitoleVikrant Shitole
Use the Schema Browser in the Force.com IDE to quickly construct a    SOQL query that will return all fields.
Mark ThomsonMark Thomson
An easy way to get the field list in an SOQL object is to use the extract feature of the Apex Data Loader.  When you build an extraction and select all fields a select query is built for you.  
S.Haider RazaS.Haider Raza
public static Map<String, String> getAllFields(String sobjectname){
  		if(!Schema.getGlobalDescribe().containsKey(sobjectname)) return new Map<String, String>{'Exception' => 'Invalid object name'};
    	Map<String, Schema.SObjectField> fields = Schema.getGlobalDescribe().get(sobjectname).getDescribe().SObjectType.getDescribe().fields.getMap();
  
    	List<String> accessiblefields = new List<String>();
  
    	for(Schema.SObjectField field : fields.values()){
      		if(field.getDescribe().isAccessible())
        		accessiblefields.add(field.getDescribe().getName());
    	}
  
    	String allfields='';
  
    	for(String fieldname : accessiblefields)
      		allfields += fieldname+',';
  
    	allfields = allfields.subString(0,allfields.length()-1);
    
    	return new Map<String, String>{sobjectname => allfields};
  	}

 
Ajish VinothAjish Vinoth
Hi Praveen,
Can you please explain what is DescribeSObjectResult res = binding.describeSObject( "Account" ); ?
and how to create DescribeSObjectResult res = binding.describeSObject( "Account" ); in scala+spark.

Thanks
praveen murugesanpraveen murugesan
Hi Ajish,

Please refer these links.

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_calls_describesobject.htm
https://developer.salesforce.com/forums/?id=906F00000008pNZIAY
Thanks.
Ajish VinothAjish Vinoth
Hi Praveen,
Here binding in sence connection?

Thanks
Ajish VinothAjish Vinoth
Hi Praveen,
i got it but 8.0 End Point
https://na2-api.salesforce.com/services/Soap/u/8.0
7.0 End Point
https://na2-api.salesforce.com/services/Soap/u/7.0 links are not working.

My problem it is not resloved. i try to do in spark+scala+salesforce.
Help me please.

Thanks
Yann COLLERYYann COLLERY
You can try:
Account acc = Database.query('SELECT ' + String.join(new List<String>(Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().keySet()), ',') + ' FROM Account');
By this way, you get all the fields of your object.