private int deleteOrphanedDocs(final Set<String> orphanedDocUuids) {
        if (!orphanedDocUuids.isEmpty()) {
            final String paramsStr = orphanedDocUuids.stream()
                    .map(uuid -> "?")
                    .collect(Collectors.joining(","));

            final String insertSql = String.format("""
                    insert into %s
                    select * from doc_permission
                    where doc_uuid in (%s)""", BACKUP_TBL_NAME, paramsStr);

            int rowCnt = DbUtil.getWithPreparedStatement(
                    securityDbConnProvider, insertSql, ThrowingFunction.unchecked(prepStmt -> {
                        int paramNo = 1;
                        for (final String docUuid : orphanedDocUuids) {
                            prepStmt.setString(paramNo++, docUuid);
                        }
                        return prepStmt.executeUpdate();
                    }));
            LOGGER.info("Inserted {} rows into {} for {} orphaned doc UUIDs",
                    rowCnt, BACKUP_TBL_NAME, orphanedDocUuids.size());

            final String deleteSql = String.format("""
                    delete from doc_permission
                    where doc_uuid in (%s)""", paramsStr);

            rowCnt = DbUtil.getWithPreparedStatement(
                    securityDbConnProvider, deleteSql, ThrowingFunction.unchecked(prepStmt -> {
                        int paramNo = 1;
                        for (final String docUuid : orphanedDocUuids) {
                            prepStmt.setString(paramNo++, docUuid);
                        }
                        return prepStmt.executeUpdate();
                    }));
            LOGGER.info("Deleted {} rows from doc_permission for {} orphaned doc UUIDs.",
                    rowCnt, orphanedDocUuids.size());
            return rowCnt;
        } else {
            return 0;
        }
    }
Previously deletion of a doc or proc_filter did not delete the doc_permission records for it.
This migration deletes any doc_permission records for a doc_uuid that cannot be found
in doc, processor_filter or explorer_node and is not the System doc (uuid == 0).
<p>
The migration copies the orphaned doc_permission records to a backup table
({@link V07_05_00_005__Orphaned_Doc_Perms#BACKUP_TBL_NAME}) before deleting them.
</p>
stroom-app/src/main/java/stroom/app/db/migration/V07_05_00_005__Orphaned_Doc_Perms.java