+ Start a Discussion
levi6dblevi6db 

List has more than 1 row for assignment to SObject error, need help please.

Hi all,

 

I created a trigger that will update the Event owner to the owner of the Lead whenever the Lead owner is changed.  We have a process where we assign a Lead to a queue with a scheduled appointment(Event) already assigned to an admin.  

 

The trigger will only fire if the Lead owner does not equal a "Queue" owner.

 

I am getting an error when:

 

 

  1. There is more than one Event on the Lead
  2. If there are no Events on the Lead
trigger ownerupdate on Lead (after Update) {

List<Event> aplist = new List<Event>();

for(Lead t : Trigger.new){

if (
(t.LeadSource == 'Telemarketing')  
&&
(t.Owner_Convert_Queue__c == NULL)
)

{Event ap = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];

            
ap.OwnerId = t.OwnerId;

aplist.add( ap );

}}
update aplist;
}

 

Any help would be appreciated.

 

Thanks,

Alex

 

mukeshrathodmukeshrathod

Hi,

   If the query can return either 0 or more than one records you need to use an array.

 

{Event [] ap = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id};

 

if(ap.size() == 1){

 

//Business logic using ap[0]

}

Pradeep_NavatarPradeep_Navatar

Use the sample code given below to avoid the error :

 

List<Event> ev = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];

 

if(ev.size() > 0)

{

   //your logic here

}

 

Hope this helps.

levi6dblevi6db

I am not sure where I add those lines, sorry.  Is it before the Trigger New or after?

 

Can you show me on my code?

bob_buzzardbob_buzzard

Revised trigger shown below.  I've highlighted the section that has changed.  

 

Your original code was assuming that there would be exactly one event associated with each lead passed into the trigger, whereas there may be 0 or more.  Thus you need to extract the list of events from the database, iterate them (if there are none, the loop will be skipped) and process each individually.

 

I'd also suggest that this trigger isn't bulk safe, as there is a SOQL query inside the for loop that traverses the trigger, but that's something for another day.

 

 

trigger ownerupdate on Lead (after Update) {

List<Event> aplist = new List<Event>();

for(Lead t : Trigger.new){

if (
(t.LeadSource == 'Telemarketing')  
&&
(t.Owner_Convert_Queue__c == NULL)
)

{List<Event> aps = [Select WhoId, Whatid, OwnerId from Event where WhoId = :t.Id];
   for (Event ap : aps)
   {       
      ap.OwnerId = t.OwnerId;

      aplist.add( ap );
   }

}}
update aplist;
}

 

 

levi6dblevi6db

Thank you so much for your help!  This worked perfectly.  I appreciate everyones help with this one.

 

Alex

levi6dblevi6db

Of course, I should have thought ahead...I am having trouble with the Class now.  I am getting the same error "ownerupdate.T1 System.QueryException: List has more than 1 row for assignment to SObject".

 

Not sure how to do this on a Class, since it was my first experience with this error on my Trigger.   Here is what I have so far:

 

 

public class ownerupdate {
static testMethod void T1() {
    Id lId;
    Id eId;
        
     //CREATE 1 LEAD
     
    Lead l = new Lead();
    l.LeadSource = 'Telemarketing';
    l.lastname = 'Doe';
    l.company = 'Test Company';
    l.ownerId = '00530000003IFwV';
    Database.insert(l);
    lId = l.Id;
    
          
    //CREATE 2 Event
    
      Event e = New Event ();
      e.DurationInMinutes     = 60;
      e.ActivityDateTime      = date.today();
      e.ownerId               = l.ownerId;
      e.WhoId                 = l.Id;
    
     Database.SaveResult result = Database.insert(e);
        eId = e.Id;
        
          update e;
          
 {List<Lead> aps = [Select Leadsource, owner_convert_queue__c, id, OwnerId from Lead
  where LeadSource = 'Telemarketing' and Owner_Convert_Queue__c = NULL];
 system.debug('@@@apo=' + aps);
}
}}

 Help would be appreciated once again!

 

Thanks,
Alex

 

bob_buzzardbob_buzzard

I can't see how the code you have posted could be causing that error - you are correctly storing the data in a list.  Is this coming from a trigger that is assuming a soql call will always return a single value?

levi6dblevi6db

Here is what happens when Validate it.  It works perfectly in the sandbox of course, but when I try and deploy to productions this is the error:

 



  • Failures & Warnings
    • Ownerupdate
      • T1
        • System.QueryException: List has more than 1 row for assignment to SObject
          • Class.ownerupdate.T1: line29, column 12 external entry point
      • Test coverage of selected Apex Trigger is 0%, at least 1% test coverage is required
    • General Warnings
      • Average test coverage across all Apex Classes and triggers is 74%, at 75% test coverage is required

The trigger that you helped me with above is the one that this class belongs with.  It can return any number of values.

 

Thanks,

Alex

Amitesh PataraAmitesh Patara
public with sharing class CreateContactFromCan {
 //Declare a method that does not return anything and takes one input parameter of a Candidate list object called candsFromTrigger
 public void createContact (List<Candidate__c> candsFromTrigger){
 //Select the Recruiting record from the database and assign to an object called candAcct from the sObject Account class
 Account candAcct = [SELECT a.Id FROM Account a WHERE a.Name = 'Recruiting'];
 //Instantiate a Contact list object from the List class called conList
 List<Contact> conList = new List<Contact>();
 //Declare a For list loop to loop through the input parameter list candsFromTrigger with an iterationvariable called currentCandidate
 for(Candidate__c currentCandidate:candsFromTrigger){
 //Instantiate an object called con from the sObject class contact
 Contact con = new Contact();
 //Set the attribute AccountID of the con object to the value of the Id attribute of the candAcct object
 con.AccountId = candAcct.Id;
 //Set the attribute Firstname of the con object to the value of the First_Name__c attribute of the currentCandidate object
 con.FirstName = currentCandidate.First_Name__c;
 //Set the attribute Lastname of the con object to the value of the Last_Name__c attribute of the currentCandidate object
 con.LastName = currentCandidate.Last_Name__c;
 //Set the attribute Email of the con object to the value of the Email__c attribute of the currentCandidate object
 con.Email = currentCandidate.Email__c;
 //Add the con object to the conList
 
 
 conList.add(con);
 }
 //Persist the conList to the database
 Database.insert(conList);
 }
}


This is what I did in challege https://trailhead.salesforce.com/content/learn/projects/quick-start-apex-coding-for-admins/create-soql-to-return-data
but  when fnally creating candidate in https://trailhead.salesforce.com/content/learn/projects/quick-start-apex-coding-for-admins/create-a-trigger
It is giving error
"CreateContact: execution of AfterInsert caused by: System.QueryException: List has more than 1 row for assignment to SObject Class.CreateContactFromCan.createContact: line 5, column 1 Trigger.CreateContact: line 5, column 1"

Please tell me