function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Shawn C KingShawn C King 

ERROR on Validating Change Sets in Prod

I am getting the error below when I try to validate my changeset.  Below that is the test method... Can some point me in the right direction?

 

Test_CC_BeazerLot_TriggerMethods.testHandleOwnerChange() Class 177 1 Failure Message: "System.DmlException: Update failed. First exception on row 0 with id a0iC0000005ies8IAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, BeazerLot_Close: execution of AfterUpdate caused by: System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Owner ID: owne...

 

private static testMethod void test_handleLotClosure() {

// Create test account with co buyer info
Account acc1 = new Account(lastname='ACC1LAST', firstname='ACC1FIRST', personEmail='test@test.test', CoBuyerLastName__c = 'CB1LAST', CoBuyerFirstName__c = 'CB1FIRST', recordTypeID = CC_BeazerLot_TriggerMethods.PERSON_RECORD_TYPE, cobuyerEmail__c = 'test@test.test');
insert acc1;

CoContact__c cc1 = new CoContact__c(CoContactAccount__c = acc1.id, CoContactfirstname__c = 'CC1FIRST', CoContactlastname__c='CC1LAST', CoContactemail__c = 'test@test.com');
insert cc1;

CoContact__c cc2 = new CoContact__c(CoContactAccount__c = acc1.id, CoContactfirstname__c = 'CC2FIRST', CoContactlastname__c='CC2LAST', CoContactemail__c = 'test@test.com');
insert cc2;

// Create test lot, referencing the above account, but is not closed
BeazerLot__c lot1 = new BeazerLot__c(name='0054', status__c = 'Spec House', accountname__c = acc1.id);
insert lot1;

// Ensure no lot relationships were created
List<CC_LotRelationship__c> lot1Rels = [SELECT id, accountname__c FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(0, lot1Rels.size());

Test.startTest();

lot1.status__c = 'Closed';
update lot1;

Test.stopTest();

// Should now have 4 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname, NHCCContactPriority__c FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(4, lot1Rels.size());

lot1 = [SELECT id, accountname__c, accountname__r.cobuyerlastname__c, accountname__r.cobuyerfirstname__c, keycontact1name__c, keycontact1name__r.accountname__c, keycontact2name__c, keycontact2name__r.accountname__r.firstname, keycontact2name__r.accountname__r.lastname FROM BeazerLot__c WHERE id = :lot1.id];

// Assert that the KeyContact1 and KeyContact2 fields have been populated correctly
for (CC_LotRelationship__c loopLR : lot1Rels) {
if (loopLR.NHCCContactPriority__c == CC_BeazerLot_TriggerMethods.KEY_CONTACT_1 ) {
System.assertEquals(lot1.keycontact1name__c, loopLR.id);
}
if (loopLR.NHCCContactPriority__c == CC_BeazerLot_TriggerMethods.KEY_CONTACT_2 ) {
System.assertEquals(lot1.keycontact2name__c, loopLR.id);
}

}

// Assert that the account names are correct
System.assertEquals(lot1.accountname__c, lot1.keycontact1name__r.accountname__c);
System.assertEquals(lot1.accountname__r.cobuyerlastname__c , lot1.keycontact2name__r.accountname__r.lastname);
System.assertEquals(lot1.accountname__r.cobuyerfirstname__c, lot1.keycontact2name__r.accountname__r.firstname);

}

 

crop1645crop1645

Shawn:

 

INVALID_CROSS_REFERENCE_KEY, Owner ID: owne...

 

Suggests that your trigger that is changing ownership is setting an ownerId to null or to an inactive owner.  Presuming you ran tests successfully in sandbox prior to deployment and that your changeset includes all the classes/triggers/workflows/field updates/etc that were changed in sandbox and thus must be deployed en masse, then the next places to look would be:

 

  • Does the sandbox mirror production in terms of workflows esp field updates
  • Does the sanbox mirror production in terms of sharing settings and org wide sharing defauts
  • Does your code rely on hard coded IDs or other values known to the sandbox but not present in PROD (like different custom settings or expecttaion of reference data)

 

 

 

Shawn C KingShawn C King

Eric, thanks for the response.  I am a .net developer that is really new to SalesForce.  In fact, this is my first SalesForce Project.  I easily changed Apex coded which is similar to Java and C#, and also did some Jquery and Html. So here are my questions pertaining to bullets you posed below:

 

  • Does the sandbox mirror production in terms of workflows esp field updates      - I found the workflows underneath setup, Create, and Workflow & Approvals.  I'm not sure exactly what I am looking for in terms of which workflow.  Do you know which one exactly I would be looking at?  I picked one randomly and it does mirror prod
  • Does the sanbox mirror production in terms of sharing settings and org wide sharing defauts -Our sales force expert departed our company, so I have noone to ask, how would I determine this.
  •  
  • Does your code rely on hard coded IDs or other values known to the sandbox but not present in PROD (like different custom settings or expecttaion of reference data) - This I am not 100% certain, but both of my environements should be the same

 

 

crop1645crop1645

Shawn

 

oh dear, you have a tougher road to follow.

 

Basically, errors in deployment from sandbox to PROD arise from these issues

 

* Sandbox testmethods rely on data that is not present in PROD; in general, testmethods should create their own testdata (test data isolation principle)

* The sandbox force.com environment is not configured the same as in PROD so when the tests run in PROD, they produce different results than in Sandbox.  The tytpical reasons why this might be the case are:

  • Different Sobject model (such as different formulas in formula fields; different RSF rules)
  • Diferent sharing model - See Setup | Security | Sharing Settings
  • Different validation rules (something fails/passes in PROD but does the opposite in Sandbox because rules are different)
  • Different workflow rules and field updates that cause actions on the database (again, in PROD, one set of actions, in sandbox, a different set)

A. Did you go to Sandbox:  Setup  | Develop | Apex Test Execution | Run all test and get a clean result?

If no, then you can debug within sandbox

 

B. Are you sure your changeset has everything that needs to be pushed to PROD? This includes all changed test classes as they rerun in PROD

 

C. If A and B pass, do you have a fullcopy sandbox that you can instantiate from PROD? If yes, then deploy your changeset to fullcopy sandbox and then debug there (no changeset validations are performed when deploying to a sandbox, fullcopy or otherwise)

 

There are a variety of ways to debug, consult the SFDC doc including good old system.debug() statements within your code

Tim BarsottiTim Barsotti

It appears you posted the wrong code for the error you are receiving. The error was on "Test_CC_BeazerLot_TriggerMethodstestHandleOwnerChange." but you "posted test_handleLotClosure".

 

Would you please post the appropriate code that is failing? Thank you!

Shawn C KingShawn C King

My aplogies Tim... here is the code:

 

private static testMethod void testHandleOwnerChange() {

// Create test account with co buyer info
Account acc1 = new Account(lastname='ACC1LAST', firstname='ACC1FIRST', personEmail='test@test.test', CoBuyerLastName__c = 'CB1LAST', CoBuyerFirstName__c = 'CB1FIRST', recordTypeID = CC_BeazerLot_TriggerMethods.PERSON_RECORD_TYPE, cobuyerEmail__c = 'test@test.test');
insert acc1;

CoContact__c cc1 = new CoContact__c(CoContactAccount__c = acc1.id, CoContactfirstname__c = 'CC1FIRST', CoContactlastname__c='CC1LAST', CoContactemail__c = 'test@test.com');
insert cc1;

CoContact__c cc2 = new CoContact__c(CoContactAccount__c = acc1.id, CoContactfirstname__c = 'CC2FIRST', CoContactlastname__c='CC2LAST', CoContactemail__c = 'test@test.com');
insert cc2;

// Create test account with co buyer info
Account acc2 = new Account(lastname='ACC2LAST', firstname='ACC2FIRST', personEmail='test@test.test', CoBuyerLastName__c = 'CB2LAST', CoBuyerFirstName__c = 'CB2FIRST', recordTypeID = CC_BeazerLot_TriggerMethods.PERSON_RECORD_TYPE, cobuyerEmail__c = 'test@test.test');
insert acc2;

// Create test lot, referencing the above account, but is not closed
BeazerLot__c lot1 = new BeazerLot__c(name='TEST 1', status__c = 'Not Closed', accountname__c = acc1.id);
insert lot1;

// Ensure no lot relationships were created
List<CC_LotRelationship__c> lot1Rels = [SELECT id, accountname__c FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(0, lot1Rels.size());

lot1.status__c = 'Closed';
update lot1;

// Should now have 4 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(4, lot1Rels.size());

lot1.accountname__c = acc2.id;
update lot1;

// Should now have 5 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(5, lot1Rels.size());

delete lot1Rels;

lot1.accountname__c = acc1.id;
update lot1;

// Should now have 2 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(2, lot1Rels.size());

lot1.accountname__c = acc2.id;
update lot1;

// Should now have 2 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(2, lot1Rels.size());

}

Shawn C KingShawn C King

I did what you said in part A... and in my Sandbox it passed successfully but in Production, it did not.  

 

Yes, my changeset includes everything.  Like I said this is my first SalesForce project and my changes seemingly has nothing to do with these test methods bombing.  

 

Lets go over the Bullet points you put down

 

  • Different Sobject model (such as different formulas in formula fields; different RSF rules) - Where exactly would i go to compare the two?  Also is there any clue which one it would be or do I have to look at all?
  • Diferent sharing model - See Setup | Security | Sharing Settings - I have check the list and these are the same
  • Different validation rules (something fails/passes in PROD but does the opposite in Sandbox because rules are different) - Not sure what you are referring to here, can you tell me where to go to look at these
  • Different workflow rules and field updates that cause actions on the database (again, in PROD, one set of actions, in sandbox, a different set) - Where exactly would i go to compare the two?  Also is there any clue which one it would be or do I have to look at all?

Your response is appreciated

crop1645crop1645

Shawn

 

Since I have no knowledge as to the scope of your org, my suggestions were more to prompt you to think (ah yes, we did change X in PROD and forgot to include in sandbox).

 


As to the other points

  • Different Sobject model (such as different formulas in formula fields; different RSF rules) - Where exactly would i go to compare the two?  Also is there any clue which one it would be or do I have to look at all? See Setup | Customize | sobject | Fields or Setup | Create | Sobject | Fields, - I would look at only those relevent to the Sobjects within test transaction in question
  • Diferent sharing model - See Setup | Security | Sharing Settings - I have check the list and these are the same
  • Different validation rules (something fails/passes in PROD but does the opposite in Sandbox because rules are different) - Not sure what you are referring to here, can you tell me where to go to look at these See Setup | Customize | sobject | Validation rules or Setup | Create | Sobject | Validation rules, - I would look at only those relevent to the Sobjects within test transaction in question
  • Different workflow rules and field updates that cause actions on the database (again, in PROD, one set of actions, in sandbox, a different set) - Where exactly would i go to compare the two?  Also is there any clue which one it would be or do I have to look at all?  Setup  | Create  | Workflows (or Field Updates) - I would look at only those relevent to the Sobjects within test transaction in question

As for the code you posted

 


Your error message implies a problem creating a BeazerLot_Close which I'm guessing occurs as part of some trigger that executes during one of the DML statements below (probably the one: update lot1 after setting lot1.status to 'Closed').

 

// Create test lot, referencing the above account, but is not closed
BeazerLot__c lot1 = new BeazerLot__c(name='TEST 1', status__c = 'Not Closed', accountname__c = acc1.id);
insert lot1;
// Ensure no lot relationships were created
List<CC_LotRelationship__c> lot1Rels = [SELECT id, accountname__c FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(0, lot1Rels.size());
lot1.status__c = 'Closed';
update lot1;

// Should now have 4 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
System.assertEquals(4, lot1Rels.size());
lot1.accountname__c = acc2.id;
update lot1;

// Should now have 5 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(5, lot1Rels.size());
delete lot1Rels;
lot1.accountname__c = acc1.id;
update lot1;
// Should now have 2 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(2, lot1Rels.size());
lot1.accountname__c = acc2.id;
update lot1;
// Should now have 2 lot relationships
lot1Rels = [SELECT id, accountname__c, accountname__r.firstname, accountname__r.lastname FROM cc_lotrelationship__c WHERE BeazerLot__c = :lot1.id];
//System.assertEquals(2, lot1Rels.size());
}

 so the problem lies in that trigger (code not disclosed yet) and how it comes to the decision as to how to set the ownerId field. It is within that logic that there's a difference between sandbox and PROD 

 

 

 

Shawn C KingShawn C King

Thanks Eric, your information has pointed me in the right direction, I got to the point where I see things are null as related object names with __r (for example anAccount.Bzh_Division__r.Name).  I was looking in Setup|Customize|Accounts and see nothing related to __r however I do see __c fields.  Can you tell me what fields __r postfix and how can I evaluate them? 

crop1645crop1645

Shawn

 

Boy, you are getting a crash course in SFDC here <g>

 

Re: Account.Bzh_Division__r.name

 


In the schema, the lookup field on Account to custom object Bzh_Division__c would be called Bzh_Division__c.  The value in that field would be an ID to a specific Bzh_Division__c row (or null, if no relationship exists for the Account in question)

 

But in APEX, if you want to reference via SOQL fields from both the Account and its lookup custom SObjects, you use the __r notation as that defines the relationship name.

 

Account a = [select id, name, bzh_division__r.name from Account where id = :myId];

 the above returns an Account SObject into varaible 'a' with access to the id and name fields from the Account as well as the name field from the lookup Bzh_Division__c custom object

 

Note that SFDC comes out of the box with its own lookup relationships, such as Opportunity -> Account. In this case, the relationship name is simply Account, not Account__r. You use the schema explorer tool (such as in Force.com Eclipse IDE) to discover these relationship names.

 

Account a = [select id, name, bzh_division__c from Account where id = :myId];

The above query returns the id, name and bzh_division__c ID from the Account object. If there is no relationship at runtime between the Account in question and its related Bzh_division__c record, then bzh_division__c will be null.

 

Overviews of this can be found here:

http://blogs.developerforce.com/developer-relations/2013/05/basic-soql-relationship-queries.html and

http://wiki.developerforce.com/page/A_Deeper_look_at_SOQL_and_Relationship_Queries_on_Force.com

 

This is all covered in complete detail here: 

http://www.salesforce.com/us/developer/docs/dbcom_soql_sosl/index_Left.htm#StartTopic=Content/sforce_api_calls_soql_relationships.htm  and I would encourage reading this carefully.

 

 

 

Shawn C KingShawn C King

Thanks for all the info Eric!  It turns down that I hunted down the issue and it had to do with permission that I didnt have to run Unit Tests in Production

crop1645crop1645

Shawn -- glad you sorted it out although I'm surprised by the fix:   'insufficient access on cross-reference entity' caused by missing run unit tests privilege in PROD?