Preface: this post is part of the Write Your First Trigger From Start to Finish series.
Good news – this step is easy!
We’ll be deploying our simple trigger from sandbox to our normal Salesforce (aka production) org. If you’re not using a sandbox connected to a real org, you don’t need to deploy – your code is already live!
We’ll be using a standard Salesforce feature called change sets to deploy.
Step 0: Connect your Sandbox and Production orgs
Setup >> Deploy >> Deployment Connections
You’ll only need to do this once!
Step 1: Navigate to the Outbound Change Sets page in Sandbox
Setup >> Deploy >> Outbound Change Sets
Step 2: Add all necessary components to a new change set, then upload to Production
In this case, we’ll add both the ForceForecasting trigger and the TestForceForecasting Apex class. We can add tons of other things like custom objects and fields, but don’t worry about that for now!
Step 3: Login to your production org, find the Inbound Change Set, and deploy!
Setup >> Deploy >> Inbound Change Sets
Once you hit the “Deploy” button (no need to validate!), you’ll have to wait a few minutes for the changes to go through. Grab yourself a nice cup of coffee while you wait and give yourself a pat on the back for deploying your first trigger!
Next Post: Intro to SOQL and why you should learn it
I can’t get to a place where tests are written
I’m going through with this same problem
Do you recommend running the test classes every time code is deployed from one org to another before it reaches prod?
Yup!
Hi David,
Why do we need to deploy the testClass from Sandbox to Production? Seems like we’d only need the Trigger in Production since all we used the testClass for is to test the Trigger by creating a new User.
Thanks for your time and help!
Best,
Brooks
Excellent question Brooks =)
The reason this is needed is because a test class success in sandbox does not guarantee the same success in production!
Your sandbox could be different vs production in terms of data, org-wide settings, config (workflows, fields), etc. When you deploy, you run the test class in both places to be safe =)
Ex: your sandbox is 1 month old. In the past week, someone else created a new workflow in prod. Your trigger & test class could work in your sandbox, but, the new workflow in prod could break it and you wouldn’t know it unless you had your test class in prod too.
Anyway that’s it in a nutshell! Deployment is a massive topic.
David
I am getting an error when attempting to access “Deployment Settings”. I am the admin on a developers copy. Is there a resolution for this?
Insufficient Privileges
You do not have the level of access necessary to perform the operation you requested. Please contact the owner of the record or your administrator if access is necessary. For more information, see Insufficient Privileges Errors.
Thanks,
Synthia
David, my questions is about a “re-deploy”. (i make an edit to my trigger)
If I edit my trigger in the sandbox, and want to deploy this EDITED version up to prod, can I just make a new changeset, add the changed trigger and redeploy? if the API name of the trigger is exactly the same… will it OVER-WRITE the previous trigger?
Yup! That’s how most people do it!
Hi David, curious about this one. If one is just adding a few more variables to an existing query in an APEX class do they need to run a test or is it ok to deploy without a test?
Either way honestly, depends on how paranoid you are
I can’t seem to deploy this because overal coverage in my org is down around 53 percent because there are triggers in there with zero coverage which I think are from the NPSP. Chatter Answers Escallation stuff, which is all the more annoying as we don’t use Chatter. I’m having a hard time finding these in Sandbox, deactivating and pushing that deactivation up to production. Any suggestions or steps to dump a trigger? I’d flat out delete them in a New York Minute if the org would allow it. Can I delete triggers in Eclipse and push the deletion up to the org that way?
Thanks!
Yes you sure can!
Delete the trigger in Eclipse, right click deploy the trigger’s folder, then uncheck everything in the folder except the “deleted” triggers.
Hey David,
I followed your tutorial and almost completed Chapter 1… Developing in the Development Sandbox. However, I stopped right before deployment with some questions that I was hoping you would be able to help me answer…
I have three questions,
1. I have failed to upload the outbound changes… I have checked your comments to Phil from the past that he needed to change the Version Settings to the latest versions for the Apex Class and Apex Trigger that you have just helped teaching us develop. However, I see that both the Class and Trigger are Version 32.0 but my production platform version is only 31.0. How can I go about upgrading my production environment to 32.0? Or should I just lower the Class and Trigger to Version 31.0 for deployment purposes?
2. Once this trigger is deployed, will I be able to turn off this ForceForecast trigger so that every time we create a new User later on in my work production org, it won’t check off the “Allow Forecasting” checkbox automatically?
3. I assume that I can do everything that you have just taught us in Chapter 1 in the Developer Console? You are just simply showing us that there are “Triggers” under each object in the SF org and how we can deploy from Force.com?
Mark
Glad to see you coding Mark =)
Yes! Lower it to 31.0. Sandboxes are on higher versions since they get the releases a little earlier =)
You can turn it off really easily if you use a Custom Setting:
https://www.sfdc99.com/2014/03/02/change-your-code-on-the-fly-using-custom-settings/
Change Sets are all you need to deploy =) You can use fancier tools like the Force.com IDE but that’s not necessary at this point =)
Hey David,
I have just successfully uploaded the Change Sets to Production for deployment. Instead of deployment, I chose to validate the code first, and it failed… Can you please verify that only the “ForceForecasting” and “TestForceForecasting” Change Set Components are supposed to be attached to this Change Set that was uploaded to Production for deployment? Like I should leave Profile Settings For Included Components blank like everything else?
Sorry to be a pain… But could you please look at these errors for me? Thanks…
Here are the 8 errors:
Class Name
Method Name
Error Message
TestForceForecasting insertNewUser System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []
Stack Trace: Class.TestForceForecasting.insertNewUser: line 21, column 1
UnitTests_setTaskOnCampaignMember test_Insert_SingleContact_SingleCampaign System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_setTaskOnCampaignMember.test_Insert_SingleContact_SingleCampaign: line 98, column 1
UnitTests_setTaskOnCampaignMember test_Insert_MultipleContacts_SingleCampaign System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_setTaskOnCampaignMember.test_Insert_MultipleContacts_SingleCampaign: line 169, column 1
UnitTests_setTaskOnCampaignMember test_Insert_MultipleContacts_MultipleCampaigns System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_setTaskOnCampaignMember.test_Insert_MultipleContacts_MultipleCampaigns: line 316, column 1
UnitTests_UpdateBrokerAccountRelations Create_SingleBrokerRelationship System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_UpdateBrokerAccountRelations.Create_SingleBrokerRelationship: line 50, column 1
UnitTests_UpdateBrokerAccountRelations Delete_MultipleBrokerRelationships System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_UpdateBrokerAccountRelations.Delete_MultipleBrokerRelationships: line 151, column 1
UnitTests_UpdateBrokerAccountRelations Create_MultipleBrokerRelationships System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_UpdateBrokerAccountRelations.Create_MultipleBrokerRelationships: line 90, column 1
UnitTests_UpdateBrokerAccountRelations UnDelete_MultipleBrokerRelationships System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, ‘Billing Country’ must contain a value: []
Stack Trace: Class.UnitTests_UpdateBrokerAccountRelations.UnDelete_MultipleBrokerRelationships: line 213, column 1
Looks like you have a lot of errors!
If you read the messages closely you should be able to figure out what needs to be done. There’s maybe one that’s difficult to decipher, and that’s the cross reference ID one. Basically the ID you’re populating in your code is an incorrect ID!
Don’t worry, this is a normal part of coding. It may seem like a lot of stuff but you’ll see it’s actually not too bad – it’s more that the error messages have a lot of fluff so it’s intimidating seeing all the text!
Hi David,
Sorry to be a pain… I have realized that the last 7 errors were like you said, actually very easy fix errors that were in place due to a managed package that it was installed into our org. However, I am still having issues with “cross reference ID”…
The only ID I see in the code is the Profile ID… I have copy and pasted everything you have written for this Class with a valid profile ID from my org, but I still receive the following when I run tests…
System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, invalid cross reference id: []
Can you please help? I’m trying really hard to get over this first hump…
Oops, nevermind! I think my org just has a lot of validation rules in place so it’s tough to write a test class on Users… I was able to pass the test in my free developer’s org :)!
I think for now, I should just go through your “Beginner’s Tutorials ” in my free developer’s org, what do you think?
Totally agree – the extra baggage will only slow you down!
When I tried step 3(Login to your production org, find the Inbound Change Set, and deploy!),
errors: field: fullName – no CustomObject named Requestor__c found?
Do you have some ideas to solve it? Thanks very much!
Missing a custom object! It could be from some old code that’s expecting that object. You can either re-create the object, or delete the old code!
Thanks, David! But, how and where can I re-create the objects? Actually, I had three objects but only two failed. If possible, would you mind giving me your email address?
Setup >> Create >> Objects will do the trick!
dvdkliu+sfdc99@gmail.com
thanks very much!
Works like a charm, Thanks! continue create new lessons.
infalliblesalesforce.blogspot.com/2014/07/how-to-deploy-from-sandbox-to.html
Hi David,
Unable to find ‘Setup >> Deploy >> Deployment Connections ‘ in my dev org.
How to proceed with this part?
Gaurav
Only possible in an actual sandbox – dev orgs don’t count!
Thanks David – great tutorial. I’m getting an error when I deploy
All components failed Version Compatibility Check.
Every component in this change set requires the “31.0” or higher platform version. Please select an organization with a platform version of “31.0” or higher.
I’ve googled and can’t find anything to help me get over this. It seems to me that I’ve got an API version mismatch somewhere but I don’t know how to fix it.
Thanks
Phil
No problem!
If you navigate to your trigger in Salesforce…
Setup >> Developer >> Apex Triggers >> Your Trigger
Then click the “Version Settings” tab and change it to 31 or higher!
David
Thanks David – great help …. don’t know how I missed it!
Hey David,
Can you please give me some links of where I can find help in writing this trigger:
Write a trigger that automatically copies an Opportunity’s Products to the Account’s Assets when the opp is closed!
Or maybe the code?
If you can follow up to Chapter 7 you have all the tools you ever need!
1. Detect that an opp is being closed:
https://www.sfdc99.com/2014/02/25/comparing-old-and-new-values-in-a-trigger/
2. Use SOQL to query for all Products
3. Use a List to create all Assets on the Account
Hope this helps!
David
Hi,
I tried creating the trigger in sandbox and when I try to upload it gives me the error that ” This organization isn’t authorized to upload change sets to other organizations. For authorization, contact the deployment connections administrators on the organizations where you want to upload changes”. Please tell me what is the issue here.
Thanks
Arpita
Make sure to do Step 0 in both your sandbox and your production orgs!
Saving this page for when I have a Sandbox to play with.. This is GREAT and VALUABLE information that you are sharing.
Hi David ,
I have two dev orgs. Will I be able to move my code from dev org 1 to dev org 2 ?
You won’t be able to do that but you can just copy and paste =) Dev orgs don’t care about code coverage or test classes!
David,
Thanks for the great tutorial, I haven’t developed for a long time but finally plucked up the courage to go beyond what Salesforce can offer in drag and drop. I found these tutorials easy to follow and nicely explained. Thanks again.
Hi David,
I just tried to deploy the ForceForecasting Trigger from a Sandbox to our Production Org, After deploying I got several error messages like the one below:
Failure Message: “System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, Allow Forecasting is not allowed for this License Type.: [ForecastEnabled]”, Failure Stack Trace: “Class.GenerateTestHierarchy.createHierarchy: line 41, column 1 Class.GenerateTestHierarchy.: line 26, col…
What do you think, what is the reason for this?
Greetings
Simeon
Make sure the user has a full (Salesforce) license in their user record and that forecasting is turned on in your production orgs!
Setup >> Customize >> Forecasts >> Forecasts Settings
Hi David,
I think I have to go further down your Guide and learn how to limit the users your trigger goes through.
The Trigger should go only through users using a specific Profile in order to be accepted in Production.
You can use the “runAs” method as well =)
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm
David,
“Runas” will only work for test classes right, then how to do this same scenario in apex class?
only way is by writing query on profile object?
Only possible in test classes! Apex runs in god mode, so it has all permissions!
David, I have created outbound change set in my sandbox yesterday (24 hours ago), I am still not seeing it in the the inbound change set in production. I see that the connection is green…while browsing on this issue I see that it usually takes time, but it has been more than 24 hours, am I missing something?
24 hours is way too long. 1 hour should be your limit! A vast majority of the time it should be < 5 minutes. Double check that you sent the outbound change set to the right place and that you're viewing from the right org too!! Also - you should receive an email when it successfully goes through!
Just wanted to say awesome dude! Appreciate the tips, been in IT 12 years and have very little coding experience – so being new to Salesforce this is the business. Keep up the great work!
Awesome! You’ll learn quicker than you expect, keep at it!!!
David
David,
Thanks a lot! your suggestion really helped me. It works fine now. Please continue giving such challenging scenarios to improve our efficiency with the language.
Ramya
Next task!
Write a trigger that automatically copies an Opportunity’s Products to the Account’s Assets when the opp is closed!
David,
I tried to put the code in trigger into a method and make it asynchronous, but future methods cannot take Sobjects as arguments. And I am not able to write a method without sobjects as arguments for this trigger. Would appreciate if you can help me in this.
Thanks
The workaround here is to use a list of IDs as the argument instead of the sObjects =)
Hi David,
Very good site and I am glad I visited your site. I was trying to write code for one of the inspirational trigger you suggested in comments “write a trigger that reassigns all of a user’s accounts, contacts, and opps to a system admin when a user is deactivated!” . I tried writing a trigger for reassigning accounts, but encountered the error “MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object”. Code is
trigger deactivetrigger on User (before update) {
List userAccounts = new List();
for(User newUser: Trigger.new)
{
User oldUser = Trigger.oldMap.get(newUser.Id);
If(newUser.IsActive != oldUser.IsActive && newUser.IsActive == False)
{
userAccounts.addAll([Select Id,OwnerId from Account where OwnerId = :newUser.Id]);
for(Account A:userAccounts)
{
A.OwnerId = ‘005i0000000j7oN’;
}
update userAccounts;
}
}
}
Please correct me and let me know a workaround for this error.
Thanks
Ramya
Very impressive stuff Ramya! Your code looks very good so far!
Looks like you’ve run into one of the “limits” of Salesforce – you’re not allowed to update both a User and an Account in the same trigger!
There’s a common workaround for this and it involves what is called an asynchronous method. Read more about it here and see if you can implement it!
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_annotation_future.htm
David
Thanks David you are defiantly one of a kind and what you are doing is amazing for us wana be developer :P
It is funny that you mention the passion i have for SF it is what got me my current role over others who had more SQL experience :)
I have just finished Chapter 2, it is excellently explained it makes understanding the query language simple and it all makes sense to me now, if i was to showed some of this i wouldn’t feel as puzzled as i would have been before Thanks :)
I am going to give your trigger a try in my dev org, the last 2 days i have found myself rushing through my workload getting everything off it so i can get back to work through your website :)
once i write a real trigger for the live org i might run it by you to make sure i’m not going to destroy everything if that is ok :P
Thanks again
Jay
More than happy to check out your code and recommend improvements! We can all learn from it together =)
Keep working hard and stay tuned for the Hall of Fame challenge!!
Hi David
I have just only found your site and have worked through the first few pages it is excellent :P i have been a SF sys admin/sys manager for nearly 4 years and am in my second company, this one is in Sydney Australia, my last was back in Liverpool, UK where i am from. I have always wanted to learn about triggers and apex and have not been able to find anything worth putting the time in until now, well done this makes it very easy to understand. I am going to work through as much of the stuff on your site as i can. I am so looking forward to writing my first trigger i just need someone to ask me for something now :). I think that triggers is my next step with SF and am really looking forward to working through your site and learning from it, it is so well explained thanks a million :)
Jay
Jay!
I spend many hours a day on Salesforce to (hopefully) help the community, and comments like yours make it all worth it =)
I wish you the best in your career, I know you will be successful because you have the passion! Post a comment if you ever need help with a trigger, I respond pretty quickly!
Finally, if you need inspiration for a trigger… write a trigger that reassigns all of a user’s accounts, contacts, and opps to a system admin when a user is deactivated! You’ll want to finish the first four chapters to know enough to do this!
Of course, if you already have your own projects or ideas for triggers, do those instead!
David
Since I am just starting to learn how do do coding and create workflows, I have my own developer’s sandbox. I highly doubt anyone will allow things from my sandbox to be deployed to production (at least not directly), but I plan to do some really great things. (With help from your tutorials… thanks!)
Is it possible to migrate something from one sandbox to another sandbox?
I know the current system administrators will want to test things I have created in their sandbox prior to deployment. Giving me the security to re-build things in the actual pre-production sandbox is not going to happen anytime in the near future.
I’d appreciate any help, or point me in the direction of a resource where I can look these types of things up. I’ve Googled this question with a few different wordings, but only found sandbox to production deployments.
Hey Monique,
For this you’ll want to look into becoming an ISV/App provider with Salesforce!
http://www.salesforce.com/partners/overview/
This lets you build apps in a sandbox, then deploy them onto other orgs as “packages”. You can put your apps on the AppExchange or simply give your partners a link to install the package in their org.
As for change sets in a developer sandbox, here’s the official word:
“Change sets can only be sent between organizations that are affiliated with a production organization—for example, a production organization and a sandbox, or two sandboxes created from the same organization.”
http://help.salesforce.com/help/doc/en/changesets.htm
So in short, become an ISV partner and code on!
David