You need to sign in to do that
Don't have an account?

transform trigger in to apex batch
Hi everyone
I would appreciate if anyone can help me with transforming the following trigger in to an apex batch
trigger ListingRankingManagementTrigger on pba__Listing__c (after insert, after update) {
// To avoid exceeding governor limits,
// use a float to reorder and have an unattended process (batch) pass it to integers again
List<pba__Listing__c> listings = Trigger.new;
Map<Id, pba__Listing__c> oldListings = null;
if (!Trigger.isInsert) {
oldListings = Trigger.oldMap;
}
for (pba__Listing__c listing : listings) {
boolean doMove = true;
integer addFactor = 0;
/ * If we move the ranking we have to locate the listing that had the new ranking before and - If the new ranking is lower than the old one, add one - If the new ranking is higher than the old one, subtract one
* /
if (!Trigger.isInsert) {
pba__Listing__c oldListing = oldListings.get(listing.Id);
doMove = (oldListing.Ranking__c != listing.Ranking__c );
if (oldListing.Ranking__c == null || listing.Ranking__c < oldListing.Ranking__c) {
addFactor = 1;
} else {
addFactor = -1;
}
} else {
// If it is an insert, it is as if the previous ranking was the highest
addFactor = 1;
}
if (listing.Ranking__c == null) {
// If ranking has not been included, we do not move
doMove = false;
}
if (doMove) {
List<pba__Listing__c> prevListings = [Select Id, Ranking__c from pba__Listing__c l where l.Ranking__c =:listing.Ranking__c AND l.id != :listing.id];
if (prevListings.size()>0) {
pba__Listing__c prevListing = prevListings.get(0);
// We have the listing that was previously in our Ranking. We are going to insert it between us and the following ranking
pba__Listing__c nextListing = null;
if (addFactor > 0) {
nextListing = [Select Ranking__c from pba__Listing__c l where l.Ranking__c > :listing.Ranking__c order by Ranking__c ASC LIMIT 1];
} else {
nextListing = [Select Ranking__c from pba__Listing__c l where l.Ranking__c < :listing.Ranking__c order by Ranking__c DESC LIMIT 1];
}
if (nextListing != null) {
prevListing.Ranking__c = (prevListing.Ranking__c + nextListing.Ranking__c) / 2;
update prevListing;
}
}
}
}
}
I would appreciate if anyone can help me with transforming the following trigger in to an apex batch
trigger ListingRankingManagementTrigger on pba__Listing__c (after insert, after update) {
// To avoid exceeding governor limits,
// use a float to reorder and have an unattended process (batch) pass it to integers again
List<pba__Listing__c> listings = Trigger.new;
Map<Id, pba__Listing__c> oldListings = null;
if (!Trigger.isInsert) {
oldListings = Trigger.oldMap;
}
for (pba__Listing__c listing : listings) {
boolean doMove = true;
integer addFactor = 0;
/ * If we move the ranking we have to locate the listing that had the new ranking before and - If the new ranking is lower than the old one, add one - If the new ranking is higher than the old one, subtract one
* /
if (!Trigger.isInsert) {
pba__Listing__c oldListing = oldListings.get(listing.Id);
doMove = (oldListing.Ranking__c != listing.Ranking__c );
if (oldListing.Ranking__c == null || listing.Ranking__c < oldListing.Ranking__c) {
addFactor = 1;
} else {
addFactor = -1;
}
} else {
// If it is an insert, it is as if the previous ranking was the highest
addFactor = 1;
}
if (listing.Ranking__c == null) {
// If ranking has not been included, we do not move
doMove = false;
}
if (doMove) {
List<pba__Listing__c> prevListings = [Select Id, Ranking__c from pba__Listing__c l where l.Ranking__c =:listing.Ranking__c AND l.id != :listing.id];
if (prevListings.size()>0) {
pba__Listing__c prevListing = prevListings.get(0);
// We have the listing that was previously in our Ranking. We are going to insert it between us and the following ranking
pba__Listing__c nextListing = null;
if (addFactor > 0) {
nextListing = [Select Ranking__c from pba__Listing__c l where l.Ranking__c > :listing.Ranking__c order by Ranking__c ASC LIMIT 1];
} else {
nextListing = [Select Ranking__c from pba__Listing__c l where l.Ranking__c < :listing.Ranking__c order by Ranking__c DESC LIMIT 1];
}
if (nextListing != null) {
prevListing.Ranking__c = (prevListing.Ranking__c + nextListing.Ranking__c) / 2;
update prevListing;
}
}
}
}
}
To change the logic into Batch Apex, you would need to create a new field to store old values of Ranking field.
Once I do that do I need to chnage the trigger? The trigger used to work fine but recently we are hitting the limists:
Developer script exception from First Mallorca : 'RankingUpdateBatch 40' : pba:Too many SOQL queries: 101
You would need to remove this logic, which you are preparing for Batch Apex, and put the logic to save the old ranking data into the new field.
After that you can create the batch apex to run your current requirement.