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
K_devK_dev 

Too many DML rows: 10001 Can anyone help on this trigger?

 

trigger createacc on Contact (after insert) {
list<Contact > con=[select id,firstname ,lastname from contact where id in:Trigger.newMap.keySet()];
list<account >acc =new list<account>();
list<contact>cc1 =new list<contact>();
for(contact c : con)
{
account a =new account ();

a.name = c.FirstName != null ? c.FirstName + ' ' + c.LastName : c.LastName;
acc.add(a);

}
insert acc;
for(account a1:acc){
system.debug('---------------------this is id --------------------'+a1.id);
for(contact c : con){
c.accountid=a1.id;
cc1.add(c);
}
}
update cc1;
}

Satyendra RawatSatyendra Rawat

Hi,

 

Write trigger before insert on contact , First create Account and then set the Account Id in contact object.

 

 

K_devK_dev

Our req: We are inserting contacts by data loader every month so it must automatically create accounts.

SeAlVaSeAlVa

Try a before insert trigger instead.

 

Something like ...

 

trigger createacc on Contact (before insert) {
	List<Account>acc = new List<Account>();
	
	for(Contact c : trigger.new)
	{
		acc.add(new Account(name = c.FirstName != null ? c.FirstName + ' ' + c.LastName : c.LastName));
	}
	insert acc;
	
	Integer i = 0;
	for(Contact c : trigger.new)
	{
		system.debug('TRIGGER|Contact|createAcc|AccountID = ' + acc.get(i).id);
		c.accountId = acc.get(i).id;
	}
}

 

 

 Regards

K_devK_dev

Error: Compile Error: line breaks not allowed in string literals at line 15 column -1

 

trigger createacc1 on Contact (before insert) {
List<Account>acc = new List<Account>();

for(Contact c : trigger.new)
{
Account a = new Account();
a.name = c.FirstName != null ? c.FirstName + ' ' + c.LastName : c.LastName;
acc.add(a);
}
insert acc;

Integer i = 0;
for(Contact c : trigger.new)
{
system.debug('TRIGGER|Contact|createAcc|AccountID = ' acc.get(i).id'); line 15
c.accountId = acc.get(i).id;
}
}

Satyendra RawatSatyendra Rawat

 

Hi,

 

What are doing for duplicate account with same name?

K_devK_dev

createacc1: execution of BeforeInsert

caused by: System.DmlException: Insert failed. First exception on row 2; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Name]: [Name]

Trigger.createacc1: line 10, column 1

K_devK_dev

I have NPI__c as an External ID and UNique field on contact by which we need to avoid duplicates not by name.

Satyendra RawatSatyendra Rawat

trigger createacc on Contact (before insert) {
List<Account>lstAcc = new List<Account>();
map<string,Account> mapAccount = new map<string,Account>();

for(Contact c : trigger.new)
{
string strName = c.FirstName != null ? c.FirstName + ' ' + c.LastName : c.LastName;
Account acc = new Account(name = strName);
mapAccount.put(strName,acc);
lstAcc.add(acc);
}
insert lstAcc;

for(Contact c : trigger.new)
{
//system.debug('TRIGGER|Contact|createAcc|AccountID = ' + acc.get(i).id);
string strName = c.FirstName != null ? c.FirstName + ' ' + c.LastName : c.LastName;
Account acc = mapAccount.get(strName);
c.accountId = acc.id;
}
}

K_devK_dev

We are inserting 4 million data does this work for this kind of insert?

K_devK_dev

createacc1: execution of BeforeInsert

caused by: System.DmlException: Insert failed. First exception on row 2; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Name]: [Name]

Trigger.createacc1: line 12, column 1

SeAlVaSeAlVa

Do you have a before insert on account that might be setting to null, blank or white-spaces its name?

Do you have a before insert on contact that might be setting to null, blank or white-spaces its LastName ?

 

What is the bulk-size of your dataloader?

Subhash GarhwalSubhash Garhwal

Hi Dev,

 

I think you try to insert and update more than 10000 at a time but in apex class you only insert/update (total) 10000 records at a time in your case you first insert new account and than update contact so it should be more than 10000 thats why it given you that error.

 

For more help about limits you can go through this link

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm

 

Thanks

 

Hit the Kudos button (star)  and Mark as solution if it post helps you 

K_devK_dev

There is not other trigger on account or contact

 

It is the first one.

K_devK_dev

It is working if I create one contact but when I data loading with 20,000 contacts Iam getting this error.

Subhash GarhwalSubhash Garhwal

But you inseting  4 million data in a time, so in your trigger you try to insert 4 million account and than update 4 million contact but in apex trigger it is not possible.

 

 

Thanks

 

Hit the Kudos button (star)  and Mark as solution if it post helps you

 

K_devK_dev

Can we change the trigger into a batch class ?

 

Which is helpful for future use also.

 

Subhash GarhwalSubhash Garhwal

I think yes and after insert all record through data loader you can run the batch.

 

Thanks

 

Hit the Kudos button (star)  and Mark as solution if it post helps you

 

K_devK_dev

Can you help me with the batch class code like trigger calling batch would work for me I think?

 

 

Subhash GarhwalSubhash Garhwal

For batch you just need to hold contact id and pass it in batch class's constructor  through apex trigger than all logic like create new account and update contact you can do in batch

 

For more details you can go through this post

 

 

http://theblogreaders.com/how-to-execute-batch-apex-using-apex-trigger/#.Up4dGNIW2Cg

 

Thanks

 

Hit the Kudos button (star)  and Mark as solution if it post helps you

K_devK_dev

Can you check this changes and correct it to exact format what I Need:

 

 

trigger insertAccount on Contact (after insert) {
Map<id, Contact> contacts = new Map<id, Contact>();
for (Integer i=0;i<Trigger.new.size();i++) {

contacts.put(Trigger.new[i].Id, Trigger.new[i]);

}
// You can execute batch apex using trigger using below codes
if (contacts.size() > 0) {
Database.executeBatch(new InsertAccounts(contacts));
}
}

 

global class InsertAccounts implements Database.Batchable<sObject> {
//map of contactid - contact
Map<Id, Contact> contactMap = new Map<Id, Contact>();
global InsertAccounts(Map<Id, Contact> contacts) {
ContactMap = contacts;
}
global Database.QueryLocator start(Database.BatchableContext BC) {
return DataBase.getQueryLocator([SELECT Id,FirstName, LastName,AccountId FROM Contact WHERE accountID IN : contactMap.keySet()]);
}
global void execute(Database.BatchableContext BC,List<Account> scopeAcc) {

for (Integer i=0;i<scopeAcc.size();i++){
scopeAcc.get(i).Area__c=ownerMap.get(scopeAcc.get(i).OwnerId).Team__c;
}
update scopeAcc;
}
global void finish(Database.BatchableContext BC) {
//Send an email to the User after your batch completes
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'info@theblogreaders.com'};
mail.setToAddresses(toAddresses);
mail.setSubject('Apex Batch Job is done');
mail.setPlainTextBody('The batch Apex Job Processed Successfully');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}

K_devK_dev

We will load them in batches of 200K. our code must work for 200k or 250k

vamshi(Nani)vamshi(Nani)

I think this is the problem with the governor limits, please try with the batch apex. Try to schedule you insert batch jobs.


K_dev wrote:

We are inserting 4 million data does this work for this kind of insert?




Subhash GarhwalSubhash Garhwal

try this one 

 

trigger insertAccount on Contact (after insert) {
Map<id, Contact> contacts = new Map<id, Contact>([Select Id, FirstName, LastName, Name From Contact Where Id IN : Trigger.newMap.keySet()]);


// You can execute batch apex using trigger using below codes
if (contacts.size() > 0)
Database.executeBatch(new InsertAccounts(contacts));
}

 

global class InsertAccounts implements Database.Batchable<sObject> {

//map of contactid - contact

Map<Id, Contact> contactMap = new Map<Id, Contact>();

global InsertAccounts(Map<Id, Contact> contacts) {
ContactMap = contacts;
}

global Database.QueryLocator start(Database.BatchableContext BC) {

return DataBase.getQueryLocator([SELECT Id,FirstName, LastName,AccountId, Name FROM Contact WHERE AccountId = null AND Id IN : contactMap.keySet()]);
}
global void execute(Database.BatchableContext BC,List<Contact> scope) {

List<Account> accounts = new List<Account>();

Map<String,Contact> mapContacts = new Map<String,Contact>();

for (Contact con : scope){

Account acc = new Account();
acc.Name = con.Name;

accounts.add(acc);

mapContacts.put(con.Name, con);
}

if(accounts.size() > 0)
insert accounts;


List<Contact> conts = new List<Contact>();

for(Account acc : [Select Id, Name From Account Where Name IN : mapContacts.keySet()]) {

if(mapContacts.containsKey(acc.Name)) {

mapContacts.get(acc.Name).AccountId = acc.Id;
conts.add(mapContacts.get(acc.Name));
}
}

if(conts.size() > 0)
update conts;

}
global void finish(Database.BatchableContext BC) {

}
}

 

use Email in finish method if you want send mail to any one

 

Thanks

 

Hit the Kudos button (star)  and Mark as solution if it post helps you 

K_devK_dev

Error: Compile Error: Apex class has Batchable or Future jobs pending or in progress at line 1 column 8

 

Please check this error while saving the batch class

K_devK_dev

Yes it is working I need to test with data loader Thanks a million!!

K_devK_dev

Does it work for batch of 200K or 250K at one time.

vamshi(Nani)vamshi(Nani)
The batch apex also follows governor limits..a batch job will perform 200 records at a time... I think so..
K_devK_dev

 As you haven't declared any scope so it is default 200 for one batch?

K_devK_dev

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY:insertAccount: System.LimitException: Attempted to schedule too many concurrent batch jobs in this org (limit is 5).

 

 

Only 800 got inserted out of 20K how to solve this issue?

 

K_devK_dev
Description

- Batch Apex can have 5 concurrent (simultaneous) jobs running in parallel.
- That is, explicitly, the number of Batch Apex jobs whose status in the AsyncApexJob table are 'Processing' or 'Preparing'.
- A job is not executing when in Queued or any other status.

- Scheduling more than 5 Batch Apex jobs returns the error "Attempted to schedule too many concurrent batch jobs in this org"
- You may sometimes receive a Developer script exception e-mail when this limit is reached, but not always. (This is also by design).

- You may attempt to use the following code sample to avoid encountering this limit, particularly if the batch is executed in a scheduled class. 


Resolution

- Count how many current jobs are being executed.
- This information is stored in the AsyncApexJob table.
- Before calling the Database.executebatch() method within a scheduled class, you should try something like:

//check if there are 5 active batch jobs
if ([SELECT count() FROM AsyncApexJob WHERE JobType='BatchApex' AND (Status = 'Processing' OR Status = 'Preparing')] < 5]){
   Database.executeBatch(batchClassInstance);
} else {
   //schedule this same schedulable class again in 30 mins
   nameOfYourSchedulableClass sc = new nameOfYourSchedulableClass();
   Datetime dt = Datetime.now() + (0.024305); // i.e. 30 mins
   String timeForScheduler = dt.format('s m H d M \'?\' yyyy');
   Id schedId = System.Schedule('MatrixRetry'+timeForScheduler,timeForScheduler,sc);
}

- In the same 'else' clause you can send an e-mail to yourselves so you're notified that the job will run a bit later than normal.

Note:

- You have can have more than 5 scheduled classes that will call Database.executeBatch() in a Queued status 

 

I found this where exactly I have to embed this code in my batch class :

 


global class InsertAccounts implements Database.Batchable<sObject> {
//map of contactid - contact
Map<Id, Contact> contactMap = new Map<Id, Contact>();
global InsertAccounts(Map<Id, Contact> contacts) {
ContactMap = contacts;
}
global Database.QueryLocator start(Database.BatchableContext BC) {
return DataBase.getQueryLocator([SELECT Id,FirstName, LastName,AccountId, Name FROM Contact WHERE AccountId = null AND Id IN : contactMap.keySet()]);
}

global void execute(Database.BatchableContext BC,List<Contact> scope)
{

List<Account> accounts = new List<Account>();
Map<String,Contact> mapContacts = new Map<String,Contact>();
for (Contact con : scope){

Account acc = new Account();
acc.Name = con.Name;
accounts.add(acc);

mapContacts.put(con.Name, con);
}
if(accounts.size() > 0)
insert accounts;

List<Contact> conts = new List<Contact>();
for(Account acc : [Select Id, Name From Account Where Name IN : mapContacts.keySet()]) {
if(mapContacts.containsKey(acc.Name)) {

mapContacts.get(acc.Name).AccountId = acc.Id;
conts.add(mapContacts.get(acc.Name));
}
}
if(conts.size() > 0)
update conts;
}
global void finish(Database.BatchableContext BC) {
}
}

 

Please let me know

 

vamshi(Nani)vamshi(Nani)

Awesome.....