+ Start a Discussion
Kenji775Kenji775 

Set Id of generic sObject for update

Hey all.

I feel like I've asked this question before, but I cannot find the answer anywhere :P

So I'm writting a service that can take a block of XML to update objects. Each XML element has a string that contains type type of object it represends and the ID of the already existing object. For example

<Object type="Contact" id="a0FU00000008h9G">
    <field id="phone">5555555555</field>
</Object>

 

 While iterating over this list of XML items, how can I create a sObject of the type specified in the type field, and set the id as well? I can get most of the way there, doing something like this...

Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Schema.SobjectType oType;

//reader.getAttributeValueAt(0) will evaluate to the object type in the XML
oType = gd.get(reader.getAttributeValueAt(0));

//If the Id is specified I need to create that type of sObject and set the ID, so I can perform an update.
//If not, I just need to create a new instance of that type of object.

if(reader.getAttributeLocalName(1) == 'id')
{
	//this fails because it says id is an unknown attribute.
	//reader.getAttributeValueAt(1) will evaluate to the id of the existing object
	thisObject= oType.newSObject(id=reader.getAttributeValueAt(1));
}
else
{
	thisObject = oType.newSObject();
}

 


 I can create a NEW instance of the type of sObject i want, but create one with the Id set so I can update it explodes. It says 

'Variable does not exist: id'

Any thoughts? Any kind of help would be much appreciated. Thanks!
 

Best Answer chosen by Admin (Salesforce Developers) 
David81David81

The newSObject method just takes an Id as an argument.

 

Try this

 

if(reader.getAttributeLocalName(1) == 'id')
{
        ID tempId = reader.getAttributeValueAt(1);
	thisObject= oType.newSObject(tempId);
}

 

All Answers

David81David81

The newSObject method just takes an Id as an argument.

 

Try this

 

if(reader.getAttributeLocalName(1) == 'id')
{
        ID tempId = reader.getAttributeValueAt(1);
	thisObject= oType.newSObject(tempId);
}

 

This was selected as the best answer
Ankit AroraAnkit Arora

So may be I am bit off track as I am bit focused on the last line you said. You need to create a new sObject and update it rather insert it. So here is the code :

 

String objName = 'contact' ;
sobject sObj = Schema.getGlobalDescribe().get(objName).newSObject('00390000007Uo1c') ;
sObj.put('lastName' , 'TestFromCode') ;
update sObj ;

 I have just passed the Id of the object I am expecting to be updated. Apologies if the answer is random.

 

 

Thanks

Ankit Arora

Blog | Facebook | Blog Page

Ankit AroraAnkit Arora
Shashikant SharmaShashikant Sharma

try it this way

 

Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Schema.SobjectType oType;

//reader.getAttributeValueAt(0) will evaluate to the object type in the XML
oType = gd.get(reader.getAttributeValueAt(0));

//If the Id is specified I need to create that type of sObject and set the ID, so I can perform an update.
//If not, I just need to create a new instance of that type of object.

if(reader.getAttributeLocalName(1) == 'id')
{
	//this fails because it says id is an unknown attribute.
	//reader.getAttributeValueAt(1) will evaluate to the id of the existing object
	thisObject= oType.newSObject();
        this.Object.put(id , reader.getAttributeValueAt(1)); 
}
else
{
	thisObject = oType.newSObject();
}

 

 

Ankit AroraAnkit Arora

I don't think we can do this way Shashikant as Id is not editable.

 

 

Thanks

Ankit Arora

Blog | Facebook | Blog Page

Kenji775Kenji775

Thanks all.

Currently it looks like 

thisObject= oType.newSObject();      
thisObject.put('id' , reader.getAttributeValueAt(1)); 

 

is going to work (it saved at least). Gotta test it out and I'll let you guys know. The other solutions seemed like they would work, but since reader.getAttributeValueAt(1) seems to return an integer (or Apex things it will) it didn't want to use that as an ID. It didn't like trying to cast it either for whatever reason.

David81David81

reader.getAttributeValueAt(1) should definitely be returning a String, not an Integer.

Shashikant SharmaShashikant Sharma

@Ankit

 

Don't come to conclusion too early my friend , Who said Id can be edited.

 

If you write

Acocount a = new Account(id='someid');

a.Name = 'UpdteAccount'; 

update a;

 

in this case i have just assigned the id to update a record which have that id.

I hope it is clear to you now.

Ankit AroraAnkit Arora

Am clear with my words, and conclusion was not too early :)

 

You can do like this :

 

Account a = new Account(id='someid');
a.Name = 'UpdteAccount'; 
update a;

 But don't think you can put Id in sObject and perform any DML.

 

I hope you have done this before saying this :)

 

 

Thanks

Ankit Arora

Blog | Facebook | Blog Page

David81David81

There is a difference between setting an Id upon construction of an sObject and trying to set the Id of an sObject that has previously be constructed. Once an sObject has been instantiated, the Id cannot be changed.

 

Trying to do so will result in an exception stating that Id is not editable.

 

If you want to set the Id of an sObject, you must do it in the constructor.

Shashikant SharmaShashikant Sharma

Let me be honest that I have  not done it, but as in this case sObject has a type as it is beaing created using global describe. So i hope it would be same as my example , let us wait for the Kenji775's reply. It will clear things. I wish he could solve his problem with that suggestion.

David81David81

It's pretty simple to test. Just copy and paste this into the system log or execute anon in eclipse.

 

Account a = [SELECT Id FROM Account LIMIT 1];
Schema.SobjectType oType = a.getSObjectType();
sobject thisObject= oType.newSObject();
thisObject.put('Id',a.Id);

 

Shashikant SharmaShashikant Sharma

I aggre with you David, you have cleared things with your example and text  and I am afraid this problem will not be solved,  I wish we could find a solution for this. Some trick .

David81David81

The solution is to just provide the Id upon construction of the object. Works fine that way.

 

Account a = [SELECT Id,Name FROM Account LIMIT 1];
system.debug('Model Account = '+a);
Schema.SObjectType oType = a.getSObjectType();
SObject thisObject = oType.newSObject(a.Id);
system.debug('New Account = '+thisObject);

 

Kenji775Kenji775

Yup, I ended up going with 

 

thisObject= oType.newSObject(reader.getAttributeValueAt(1));

 

Works perfect. I was so close on my first attempt too :P

Thanks everyone! 

Ankit AroraAnkit Arora

Finally we have the right choice.

 

 

Thanks

Ankit Arora

Blog | Facebook | Blog Page