0

我有两个自定义对象,列表和交易。最初,我在列表对象的事务对象上有一个查找字段。我设置了 Apex 托管共享,以便与相关列表对象上的多个用户查找字段共享交易。它工作得很好。

我将事务对象上的列表字段的字段类型更改为 Master-Detail,现在每次尝试保存新事务时都会收到以下错误:

“TransactionApexSharing:AfterInsert 的执行导致:第 1 行,第 1 列:触发器主体无效并且重新编译失败:实体不可组织访问”

Transaction 和 Listing 对象都设置为 Private,我在代码中找不到任何拼写错误。触发器在使用 Lookup 字段后未更改。

这是我的代码:

trigger TransactionApexSharing on Transaction__c (after insert, after update) {

if(trigger.isInsert || trigger.isUpdate){



    Set<id> triggerIds = trigger.newMap.keyset();

    List<Transaction__c> listWithParentData = [select Listing__r.Listing_Agent_1__r.id, Listing__r.Listing_Agent_2__r.id, Listing__r.Listing_Agent_3__r.id from Transaction__c where id in :triggerIds];


    List<Transaction__Share> tranShrs = new List<Transaction__Share>();

    Transaction__Share laShr;
    Transaction__Share la2Shr;
    Transaction__Share la3Shr;
    Transaction__Share saShr;
    Transaction__Share sa2Shr;
    Transaction__Share sa3Shr;


    for(Transaction__c atransaction : listWithParentData){

        laShr = new Transaction__Share();
        la2Shr = new Transaction__Share();
        la3Shr = new Transaction__Share();

        laShr.ParentId = atransaction.Id;
        la2Shr.ParentId = atransaction.Id;
        la3Shr.ParentId = atransaction.Id;

        if (atransaction.Listing__r.Listing_Agent_1__c != null)
        {
            // Set the ID of user or group being granted access 
            laShr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_1__c;
            // Set the access level 
            laShr.AccessLevel = 'edit';
            // Set the Apex sharing reason 
            laShr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            // Add objects to list for insert 
            tranShrs.add(laShr);
        }

        if (atransaction.Listing__r.Listing_Agent_2__c != null)
        {
            la2Shr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_2__c;
            la2Shr.AccessLevel = 'edit';
            la2Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(la2Shr);
        }

        if (atransaction.Listing__r.Listing_Agent_3__c != null)
        {
            la3Shr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_3__c;
            la3Shr.AccessLevel = 'edit';
            la3Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(la3Shr);
        }

    }

    for(Transaction__c mytransaction : trigger.new){
        // Instantiate the sharing objects 

        saShr = new Transaction__Share();
        sa2Shr = new Transaction__Share();
        sa3Shr = new Transaction__Share();

        // Set the ID of record being shared 


        saShr.ParentId = mytransaction.Id;
        sa2Shr.ParentId = mytransaction.Id;
        sa3Shr.ParentId = mytransaction.Id;


        if (mytransaction.Selling_Agent_1_User__c != null)
        {
            saShr.UserOrGroupId = mytransaction.Selling_Agent_1_User__c;
            saShr.AccessLevel = 'edit';
            saShr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(saShr);
        }

        if (mytransaction.Selling_Agent_2_User__c != null)
        {
            sa2Shr.UserOrGroupId = mytransaction.Selling_Agent_2_User__c;
            sa2Shr.AccessLevel = 'edit';
            sa2Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(sa2Shr);
        }

        if (mytransaction.Selling_Agent_3_User__c != null)
        {
            sa3Shr.UserOrGroupId = mytransaction.Selling_Agent_3_User__c;
            sa3Shr.AccessLevel = 'edit';
            sa3Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(sa3Shr);
        }



    }

    // Insert sharing records and capture save result  

    // The false parameter allows for partial processing if multiple records are passed  

    // into the operation  

    Database.SaveResult[] lsr = Database.insert(tranShrs,false);

    // Create counter 

    Integer i=0;

    // Process the save results 

    for(Database.SaveResult sr : lsr){
        if(!sr.isSuccess()){
            // Get the first save result error 

            Database.Error err = sr.getErrors()[0];

            // Check if the error is related to a trivial access level 

            // Access levels equal or more permissive than the object's default  

            // access level are not allowed.  

            // These sharing records are not required and thus an insert exception is  

            // acceptable.  

            if(!(err.getStatusCode() == StatusCode.FIELD_FILTER_VALIDATION_EXCEPTION  
                                           &&  err.getMessage().contains('AccessLevel'))){
                // Throw an error when the error is not related to trivial access level. 

                trigger.newMap.get(tranShrs[i].ParentId).
                  addError(
                   'Unable to grant sharing access due to following exception: '
                   + err.getMessage());
            }
        }
        i++;
    } 
}

}
4

1 回答 1

1

当您将关系从查找翻转到主细节时,会发生很多变化。你失去了对细节的细粒度访问,就是这样。无论用户对主人拥有什么权利 - 他也拥有他们的详细信息(好的,不包括个人资料中的“读取/创建/编辑/删除”之类的东西,我说的是对特定记录的访问,而不是一般权限) .

  1. 在细节上“OwnerId”将消失(无法查询、描述等)
  2. 如果你曾经有过一些更好的点:
    • 需要详细审批流程,突然不能使用队列,需要直接指定用户。
    • 用户在列表视图或报告中询问“我的交易发生了什么”
  3. 最后但同样重要的是 - Detail__Share 表也消失了。

尝试在沙箱中编辑您的触发器(只需添加 1 个空格或其他内容),它可能会抱怨没有这样的 table Transaction_Share

您可以确保代理对父列表具有编辑权限(但这意味着他们可以编辑任何相关事务)并放弃触发器或撤消 MD。这真的是一个回到你的用户并询问业务逻辑的案例;)

你为什么把它转给MD?如果事实证明您无法承受失去对每个事务的这种细粒度的编辑访问权限,则可以使用一些代码来完成级联删除、汇总等操作。

但是在快速查看您的代码之后,在我看来,您可以控制列表级别的访问而不是详细信息?

于 2013-01-19T09:30:32.503 回答