Bạn đang gặp rắc rối với trigger ContentDocumentLink
trong Salesforce, đặc biệt là lỗi FIELD_INTEGRITY_EXCEPTION
sau khi insert? Bài viết này sẽ cung cấp giải pháp chi tiết, dễ hiểu và chuẩn SEO để bạn xử lý vấn đề này một cách hiệu quả. Chúng ta sẽ cùng nhau tìm hiểu nguyên nhân gây ra lỗi, các phương pháp tránh vòng lặp đệ quy và tối ưu hóa trigger của bạn.
Lỗi FIELD_INTEGRITY_EXCEPTION
thường xảy ra khi bạn cố gắng tạo một bản ghi ContentDocumentLink
trùng lặp. Điều này có nghĩa là bạn đang cố gắng liên kết một ContentDocument
(ví dụ: Tệp hoặc Ghi chú) với một LinkedEntity
(ví dụ: Bản ghi Tài khoản hoặc Nhóm Chatter) mà liên kết đó đã tồn tại. Lỗi này thường xuyên xuất hiện khi trigger ContentDocumentLink
được kích hoạt một cách đệ quy.
Một ví dụ điển hình là khi bạn tạo một trigger để tự động chia sẻ tệp với một Nhóm Chatter mỗi khi tệp đó được tải lên. Nếu trigger không được thiết kế cẩn thận, nó có thể tạo ra một vòng lặp vô hạn, trong đó việc tạo một ContentDocumentLink
mới lại kích hoạt trigger, dẫn đến việc tạo một ContentDocumentLink
khác, và cứ thế tiếp diễn.
Để giải quyết vấn đề này, chúng ta cần đảm bảo rằng trigger của bạn chỉ được kích hoạt một lần cho mỗi bản ghi và rằng bạn không cố gắng tạo các bản ghi ContentDocumentLink
trùng lặp. Dưới đây là một số chiến lược bạn có thể áp dụng:
Một cách phổ biến để ngăn chặn vòng lặp đệ quy là sử dụng một biến `static Boolean` trong một lớp helper. Biến này sẽ được đặt thành `true` trước khi trigger được thực thi và sau đó được đặt thành `false` bên trong trigger. Điều này đảm bảo rằng trigger chỉ thực thi logic của nó một lần duy nhất trong mỗi giao dịch.
Ví dụ:
public class ContentDocumentLinkHelper {
public static Boolean isRunning = false;
}
trigger ContentDocumentLinkTrigger on ContentDocumentLink (after insert) {
if (ContentDocumentLinkHelper.isRunning) {
return;
}
ContentDocumentLinkHelper.isRunning = true;
// Logic trigger của bạn ở đây
ContentDocumentLinkHelper.isRunning = false;
}
Trước khi bạn cố gắng tạo một bản ghi ContentDocumentLink
mới, hãy kiểm tra xem bản ghi đó đã tồn tại hay chưa. Bạn có thể thực hiện việc này bằng cách truy vấn cơ sở dữ liệu để tìm kiếm một bản ghi ContentDocumentLink
có cùng ContentDocumentId
và LinkedEntityId
.
Ví dụ:
List existingLinks = [SELECT Id FROM ContentDocumentLink WHERE ContentDocumentId = :cdl.ContentDocumentId AND LinkedEntityId = :collabGroup.Id LIMIT 1];
if (existingLinks.isEmpty()) {
ContentDocumentLink cdlNewLink = new ContentDocumentLink();
cdlNewLink.ContentDocumentId = cdl.ContentDocumentId;
cdlNewLink.LinkedEntityId = collabGroup.Id;
cdlNewLink.ShareType = 'V';
cdlNewLink.Visibility = 'AllUsers';
insert cdlNewLink;
}
Việc thực hiện truy vấn SOQL bên trong vòng lặp for là một trong những lỗi phổ biến nhất trong Apex. Điều này có thể nhanh chóng vượt quá giới hạn của chính phủ và làm chậm hiệu suất của ứng dụng của bạn. Thay vào đó, hãy thu thập tất cả các ID cần thiết và thực hiện một truy vấn SOQL duy nhất bên ngoài vòng lặp.
Ví dụ (Sửa lại từ ví dụ gốc):
public static void shareWithCollaborationGroup(List cdlNeedLinks, SObject collabGroup) {
Set contentDocumentIds = new Set();
for (ContentDocumentLink cdl : cdlNeedLinks) {
contentDocumentIds.add(cdl.ContentDocumentId);
}
// Truy vấn tất cả các ContentDocumentLink hiện có
List existingLinks = [
SELECT ContentDocumentId, LinkedEntityId
FROM ContentDocumentLink
WHERE ContentDocumentId IN :contentDocumentIds AND LinkedEntityId = :collabGroup.Id
];
Set existingLinkIds = new Set();
for (ContentDocumentLink link : existingLinks) {
existingLinkIds.add(link.ContentDocumentId);
}
List linksToInsert = new List();
for (ContentDocumentLink cdl : cdlNeedLinks) {
if (!existingLinkIds.contains(cdl.ContentDocumentId)) {
ContentDocumentLink cdlNewLink = new ContentDocumentLink();
cdlNewLink.ContentDocumentId = cdl.ContentDocumentId;
cdlNewLink.LinkedEntityId = collabGroup.Id;
cdlNewLink.ShareType = 'V';
cdlNewLink.Visibility = 'AllUsers';
linksToInsert.add(cdlNewLink);
}
}
try {
if (!linksToInsert.isEmpty()) {
insert linksToInsert;
}
} catch (DmlException e) {
System.debug('Exception occurred on insert: ' + e.getMessage());
}
}
Việc xử lý các trigger ContentDocumentLink
có thể phức tạp, đặc biệt là khi bạn phải đối mặt với các vấn đề về đệ quy và tính toàn vẹn dữ liệu. Bằng cách áp dụng các chiến lược được trình bày trong bài viết này, bạn có thể tạo ra các trigger mạnh mẽ và đáng tin cậy để tự động hóa các quy trình liên quan đến tệp và chia sẻ trong Salesforce. Hãy nhớ kiểm tra kỹ lưỡng trigger của bạn trong môi trường sandbox trước khi triển khai chúng vào môi trường production.
Bài viết liên quan