@Override
    public void send(final Message message) {
      try {
        TransactionInvokerUtil.invoke(
            _transactionAttribute,
            new Callable<Void>() {

              @Override
              public Void call() throws Exception {
                CleanTransactionSynchronousDestination.super.send(message);

                return null;
              }
            });
      } catch (Throwable t) {
        throw new RuntimeException(t);
      }
    }
  protected long doPerformActions(long previousPrimaryKey) throws PortalException {

    final DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(_clazz, _classLoader);

    Property property = PropertyFactoryUtil.forName(_primaryKeyPropertyName);

    dynamicQuery.add(property.gt(previousPrimaryKey));

    dynamicQuery.addOrder(OrderFactoryUtil.asc(_primaryKeyPropertyName));

    dynamicQuery.setLimit(0, _interval);

    addDefaultCriteria(dynamicQuery);

    addCriteria(dynamicQuery);

    Callable<Long> callable =
        new Callable<Long>() {

          @Override
          public Long call() throws Exception {
            List<Object> objects =
                (List<Object>) executeDynamicQuery(_dynamicQueryMethod, dynamicQuery);

            if (objects.isEmpty()) {
              return -1L;
            }

            for (Object object : objects) {
              performAction(object);
            }

            if (objects.size() < _interval) {
              return -1L;
            }

            BaseModel<?> baseModel = (BaseModel<?>) objects.get(objects.size() - 1);

            return (Long) baseModel.getPrimaryKeyObj();
          }
        };

    TransactionAttribute transactionAttribute = getTransactionAttribute();

    try {
      if (transactionAttribute == null) {
        return callable.call();
      } else {
        return TransactionInvokerUtil.invoke(transactionAttribute, callable);
      }
    } catch (Throwable t) {
      if (t instanceof PortalException) {
        throw (PortalException) t;
      }

      if (t instanceof SystemException) {
        throw (SystemException) t;
      }

      throw new SystemException(t);
    } finally {
      indexInterval();
    }
  }
  @Override
  protected void doProcessAction(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);

    try {
      BlogsEntry entry = null;
      String oldUrlTitle = StringPool.BLANK;
      List<BlogsEntryAttachmentFileEntryReference> blogsEntryAttachmentFileEntryReferences = null;

      UploadException uploadException =
          (UploadException) actionRequest.getAttribute(WebKeys.UPLOAD_EXCEPTION);

      if (uploadException != null) {
        if (uploadException.isExceededLiferayFileItemSizeLimit()) {
          throw new LiferayFileItemException();
        } else if (uploadException.isExceededSizeLimit()) {
          throw new FileSizeException(uploadException.getCause());
        }

        throw new PortalException(uploadException.getCause());
      } else if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {

        Callable<Object[]> updateEntryCallable = new UpdateEntryCallable(actionRequest);

        Object[] returnValue =
            TransactionInvokerUtil.invoke(_transactionAttribute, updateEntryCallable);

        entry = (BlogsEntry) returnValue[0];
        oldUrlTitle = ((String) returnValue[1]);
        blogsEntryAttachmentFileEntryReferences =
            ((List<BlogsEntryAttachmentFileEntryReference>) returnValue[2]);
      } else if (cmd.equals(Constants.DELETE)) {
        deleteEntries(actionRequest, false);
      } else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
        deleteEntries(actionRequest, true);
      } else if (cmd.equals(Constants.RESTORE)) {
        restoreTrashEntries(actionRequest);
      } else if (cmd.equals(Constants.SUBSCRIBE)) {
        subscribe(actionRequest);
      } else if (cmd.equals(Constants.UNSUBSCRIBE)) {
        unsubscribe(actionRequest);
      }

      String redirect = ParamUtil.getString(actionRequest, "redirect");
      boolean updateRedirect = false;

      String portletId = HttpUtil.getParameter(redirect, "p_p_id", false);

      if (Validator.isNotNull(oldUrlTitle)) {
        String oldRedirectParam = PortalUtil.getPortletNamespace(portletId) + "redirect";

        String oldRedirect = HttpUtil.getParameter(redirect, oldRedirectParam, false);

        if (Validator.isNotNull(oldRedirect)) {
          String newRedirect = HttpUtil.decodeURL(oldRedirect);

          newRedirect = StringUtil.replace(newRedirect, oldUrlTitle, entry.getUrlTitle());
          newRedirect = StringUtil.replace(newRedirect, oldRedirectParam, "redirect");

          redirect = StringUtil.replace(redirect, oldRedirect, newRedirect);
        } else if (redirect.endsWith("/blogs/" + oldUrlTitle)
            || redirect.contains("/blogs/" + oldUrlTitle + "?")
            || redirect.contains("/blog/" + oldUrlTitle + "?")) {

          redirect = StringUtil.replace(redirect, oldUrlTitle, entry.getUrlTitle());
        }

        updateRedirect = true;
      }

      int workflowAction =
          ParamUtil.getInteger(
              actionRequest, "workflowAction", WorkflowConstants.ACTION_SAVE_DRAFT);

      boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");

      if (ajax) {
        JSONObject jsonObject = JSONFactoryUtil.createJSONObject();

        JSONArray jsonArray = JSONFactoryUtil.createJSONArray();

        for (BlogsEntryAttachmentFileEntryReference blogsEntryAttachmentFileEntryReference :
            blogsEntryAttachmentFileEntryReferences) {

          JSONObject blogsEntryFileEntryReferencesJSONObject = JSONFactoryUtil.createJSONObject();

          blogsEntryFileEntryReferencesJSONObject.put(
              "attributeDataImageId", EditorConstants.ATTRIBUTE_DATA_IMAGE_ID);
          blogsEntryFileEntryReferencesJSONObject.put(
              "fileEntryId",
              String.valueOf(
                  blogsEntryAttachmentFileEntryReference.getTempBlogsEntryAttachmentFileEntryId()));
          blogsEntryFileEntryReferencesJSONObject.put(
              "fileEntryUrl",
              PortletFileRepositoryUtil.getPortletFileEntryURL(
                  null,
                  blogsEntryAttachmentFileEntryReference.getBlogsEntryAttachmentFileEntry(),
                  StringPool.BLANK));

          jsonArray.put(blogsEntryFileEntryReferencesJSONObject);
        }

        jsonObject.put("blogsEntryAttachmentReferences", jsonArray);

        jsonObject.put("entryId", entry.getEntryId());
        jsonObject.put("redirect", redirect);
        jsonObject.put("updateRedirect", updateRedirect);

        JSONPortletResponseUtil.writeJSON(actionRequest, actionResponse, jsonObject);

        return;
      }

      if ((entry != null) && (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {

        redirect = getSaveAndContinueRedirect(actionRequest, entry, redirect);

        sendRedirect(actionRequest, actionResponse, redirect);
      } else {
        WindowState windowState = actionRequest.getWindowState();

        if (!windowState.equals(LiferayWindowState.POP_UP)) {
          sendRedirect(actionRequest, actionResponse, redirect);
        } else {
          redirect = PortalUtil.escapeRedirect(redirect);

          if (Validator.isNotNull(redirect)) {
            if (cmd.equals(Constants.ADD) && (entry != null)) {
              String namespace = PortalUtil.getPortletNamespace(portletId);

              redirect =
                  HttpUtil.addParameter(
                      redirect, namespace + "className", BlogsEntry.class.getName());
              redirect = HttpUtil.addParameter(redirect, namespace + "classPK", entry.getEntryId());
            }

            sendRedirect(actionRequest, actionResponse, redirect);
          }
        }
      }
    } catch (Exception e) {
      String mvcPath = "/blogs/edit_entry.jsp";

      if (e instanceof NoSuchEntryException || e instanceof PrincipalException) {

        SessionErrors.add(actionRequest, e.getClass());

        mvcPath = "/blogs/error.jsp";
      } else if (e instanceof EntryContentException
          || e instanceof EntryCoverImageCropException
          || e instanceof EntryDescriptionException
          || e instanceof EntryDisplayDateException
          || e instanceof EntrySmallImageNameException
          || e instanceof EntrySmallImageScaleException
          || e instanceof EntryTitleException
          || e instanceof FileSizeException
          || e instanceof LiferayFileItemException
          || e instanceof SanitizerException) {

        SessionErrors.add(actionRequest, e.getClass());
      } else if (e instanceof AssetCategoryException || e instanceof AssetTagException) {

        SessionErrors.add(actionRequest, e.getClass(), e);
      } else {
        Throwable cause = e.getCause();

        if (cause instanceof SanitizerException) {
          SessionErrors.add(actionRequest, SanitizerException.class);
        } else {
          throw e;
        }
      }

      actionResponse.setRenderParameter("mvcPath", mvcPath);
    } catch (Throwable t) {
      _log.error(t, t);

      actionResponse.setRenderParameter("mvcPath", "/blogs/error.jsp");
    }
  }