9

I need an approach to allow delegated admins (i.e., non-Administators) to add members to Public Groups and Collaboration Groups (the GroupMember and CollaborationGroupMember objects).

I added a custom object (UserGroupRequest__c) to capture which Users should be added/removed to which Groups.

I've also built a batchable class to process the requests.

However, GroupMember is a Setup object, and CollaborationGroupMember is not. So this doesn't work if I combine the operations in a single batchable class.

Should I instead be using 2 batch classes, calling one from the finish method of the other?

Any recommendations on how best to proceed? Am I way off base?

Would a trigger on the Request object perhaps be better? I'm guessing that there may be a permission problem if this is attempted via a trigger as the delegated admins won't be able to add users to public Groups. Also, I'm guessing the trigger approach would run into the same mixed DML issue - on Insert of the Custom object, I would need to Insert/Delete from GroupMember and from CollaborationGroupMember, and then perform a 2nd update on the Custom object to indicate that processing was completed...

3
  • salesforce.stackexchange.com/questions/23574/… - I'm not saying this is a duplicate but could help you a lot :) As for "trigger on the Request" -> you're right. It would work only if the setup part (Queue) would be in @future I think.
    – eyescream
    Commented Jan 16, 2014 at 13:28
  • Thanks eyescream - sorry I didn't see that message with the link showing how GroupMember can be manipulated by non-admins. I'm hoping to make the setup/non-setup updates virtually the same transaction (one button click for example) even though I guess they need to be separated due to the mixed DML issue...
    – newbie
    Commented Jan 16, 2014 at 13:46
  • Welcome to SFSE! Commented Jan 16, 2014 at 13:56

1 Answer 1

3

How about something like this in Batch Apex:

public class MixedDmlBatch implements Database.Batchable<Object> {

    public interface IAction 
    {
        void execute();
    }

    public class SetupDmlAction implements IAction
    {
        public void execute()
        {
            /// do your setup DML
        }
    }

    public class NonSetupDmlAction implements IAction
    {
        public void execute()
        {
            // do your non Setup DML
        }
    }


    public List<Object> start(Database.BatchableContext context)
    {
        List<IAction> actions = new List<IAction>();
        actions.add(new SetupDmlAction());
        actions.add(new NonSetupDmlAction());
        return actions;
    }

    public void execute(Database.BatchableContext context, List<Object> scope)
    {
        for(IAction action : (List<IAction>)scope)
        {
            action.execute();
        }
    }

    public void finish(Database.BatchableContext context) {}

}

When you call your batch apex give it a batch size of 1

MixedDmlBatch batch = new MixedDmlBatch();
Database.executeBatch( batch, 1 );

There are limitations to this approach of course, but it works for me on a common requirement we have within our app.

5
  • 2
    Have you got something against spaces and CR's herp? @user320 ;) Commented Jan 16, 2014 at 16:35
  • 1
    nah, just code that doesn't compile ;) Commented Jan 16, 2014 at 16:55
  • 1
    :D a minor detail Commented Jan 16, 2014 at 16:59
  • How/where do you pass in the data on which to operate? Or do you simply query for it inside SetupDmlAction and NonSetupDmlAction?
    – Benj
    Commented Oct 23, 2014 at 13:58
  • 1
    That would be entirely up to you and your requirement @Benj . The way I'm using it, its to perform the same action whilst being a member of a number of different queues, so I query the data in the start method and then build the actions list accordingly. My use case only returns a few records from the database, and honestly we're only using batch apex so we can get a new execution context for each record. Commented Oct 23, 2014 at 14:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .