+ Start a Discussion
GRStevenBrookesGRStevenBrookes 

Help with' List has more than 1 row for assignment to SObject'

Evening World,

 

I am using the following Apex Trigger and Test Class:

 

trigger AutoAllocateDelegatesToTrainingActions on Training__c (before insert) {
{
	List<Employee_Training_Action__c> listETA = new List<Employee_Training_Action__c> ();
	
	for (Training__C T : trigger.new)
	if(Trigger.isInsert)
	{
	
		
			Employees__c Emp = [SELECT Id FROM Employees__c WHERE Works_Nights_Weekdays__c = TRUE];
			
			listETA.add(new Employee_Training_Action__c(
			Training_Action__c = T.id,
			Employee__c = Emp.id));
		
		if(listETA.size() >0)
		{
			insert listETA;	
		}
	}
}
}

 

@isTest
private class Test_TA_DelegateAllocation {
static testMethod void myUnitTest9()
{
	Service_Agreement__c SA = new Service_Agreement__c ();
	SA.Name = 'Test SA';
	insert SA;
	Training__c TR = new Training__c ();
	TR.Service_Agreement__c=SA.Id;
	insert TR;
	Employee_Training_Action__c ETA = new Employee_Training_Action__c ();
	ETA.Training_Action__c=TR.Id;
	ETA.Employee__c = 'a0l20000001IYYN';
try{	
	insert ETA;}
 catch(System.DmlException e){            
 System.debug('we caught a dml exception: ' + e.getDmlMessage(0));
	}
}
}

 However, when deploying to production I am getting the following error:

 

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AutoAllocateDelegatesToTrainingActions: execution of BeforeInsert

caused by: System.QueryException: List has more than 1 row for assignment to SObject

Trigger.AutoAllocateDelegatesToTrainingActions: line 10, column 23: []

 

I understand what the error is saying, and it is correct, there will be more than one record to create, however, how do i tell the system that this is 'ok'!

 

Help much apprecaited.

 

Steve

Best Answer chosen by Admin (Salesforce Developers) 
trictric

Hi ,

 

Try below given code and see if it helps.

 

 

 

trigger AutoAllocateDelegatesToTrainingActions on Training__c (before insert) {
{
    List<Employee_Training_Action__c> listETA = new List<Employee_Training_Action__c> ();
    
    for (Training__C T : trigger.new)
    if(Trigger.isInsert)
    {
    
        
            list<Employees__c> Emp = [SELECT Id FROM Employees__c WHERE Works_Nights_Weekdays__c = TRUE];
            
            for(Employees__c lipo:emp)
            {
            
            Employee_Training_action__c a =new Employee_Training_action__c(Training_Action__c = T.id,Employee__c = lipo.id);
            listeta.add(a);
            }
            
           
        if(listETA.size() >0)
        {
            insert listETA;
        }
    
}
}
}

 

 

 

Tric.

All Answers

trictric

Hi ,

 

My guess ia th that below given line is the culprit.If your query is returning more than one row then you should be storing returned results in some array not in an object.

 

 

Employees__c Emp = [SELECT Id FROM Employees__c WHERE Works_Nights_Weekdays__c = TRUE]

 

 

 

Trick 

 

 

 

 

GRStevenBrookesGRStevenBrookes
Thanks for reply...so how to I get the results into an array and then how do I insert all results

Steve
AmitSahuAmitSahu
trigger AutoAllocateDelegatesToTrainingActions on Training__c (before insert) {
{
	List<Employee_Training_Action__c> listETA = new List<Employee_Training_Action__c> ();
	
	for (Training__C T : trigger.new)
	if(Trigger.isInsert)
	{
	
		
			Employees__c Emp = [SELECT Id FROM Employees__c WHERE Works_Nights_Weekdays__c = TRUE];   //Returns more than 1 records so you will need a List<Employees__c> to store them and iterate over them
			 
			listETA.add(new Employee_Training_Action__c(
			Training_Action__c = T.id,
			Employee__c = Emp.id));
		
		if(listETA.size() >0)
		{
			insert listETA;	
		}
	}
}
}

 

GRStevenBrookesGRStevenBrookes
Hi thanks for reply, I thought I had already done that?? See above.
AmitSahuAmitSahu

i did not change any code i just pointed out that you are assigning a list to a object which is retutning more than 1 record. may be you have to take list of object in that case.......

GRStevenBrookesGRStevenBrookes

Thank you for your help - any ideas on how this can be achieved 'Array' or 'Iterate' are not words I have come up against in my Apex learning journey as of yet.

trictric

Hi ,

 

Try below given code and see if it helps.

 

 

 

trigger AutoAllocateDelegatesToTrainingActions on Training__c (before insert) {
{
    List<Employee_Training_Action__c> listETA = new List<Employee_Training_Action__c> ();
    
    for (Training__C T : trigger.new)
    if(Trigger.isInsert)
    {
    
        
            list<Employees__c> Emp = [SELECT Id FROM Employees__c WHERE Works_Nights_Weekdays__c = TRUE];
            
            for(Employees__c lipo:emp)
            {
            
            Employee_Training_action__c a =new Employee_Training_action__c(Training_Action__c = T.id,Employee__c = lipo.id);
            listeta.add(a);
            }
            
           
        if(listETA.size() >0)
        {
            insert listETA;
        }
    
}
}
}

 

 

 

Tric.

This was selected as the best answer
trictric

Though I don't understand what you trying to accomplish with your code.In Before insert trigger you are tyrying to assign new record id to another object's field and then inserting in the database.

 

 

You are assigning record id which hasn't been created yet so it is going to put null value in the field to which you are assigning your record id .I hope you do not deploy your code to production environment.

 

I my opinion you should have been using After insert or after update trigger. 

 

Thanks,

Trick

GRStevenBrookesGRStevenBrookes

thanks for your reply tric.

 

Effectively, what happens here is that we have a training course, when the course record is created (Training__C), it should look up the delegates that are eligible (Employees__C) that meet the relevent criteria and then create a training action which is just a joining object between the Employees__c to Training__c to allow a many to many relationship.

 

Hope this better explains what we are trying to achieve.

GRStevenBrookesGRStevenBrookes

Thanks Tric - have got round to testing this - and as an 'After Insert' it works like a dream! Thank you Very Much

 

:-)