public Attachment execute(CommandContext commandContext) {
    AttachmentEntity attachment = new AttachmentEntity();
    attachment.setName(attachmentName);
    attachment.setDescription(attachmentDescription);
    attachment.setType(attachmentType);
    attachment.setTaskId(taskId);
    attachment.setProcessInstanceId(processInstanceId);
    attachment.setUrl(url);

    DbSqlSession dbSqlSession = commandContext.getDbSqlSession();
    dbSqlSession.insert(attachment);

    if (content != null) {
      byte[] bytes = IoUtil.readInputStream(content, attachmentName);
      ByteArrayEntity byteArray = new ByteArrayEntity(bytes);
      dbSqlSession.insert(byteArray);
      attachment.setContentId(byteArray.getId());
    }

    CommentManager commentManager = commandContext.getCommentManager();
    if (commentManager.isHistoryEnabled()) {
      String userId = Authentication.getAuthenticatedUserId();
      CommentEntity comment = new CommentEntity();
      comment.setUserId(userId);
      comment.setType(CommentEntity.TYPE_EVENT);
      comment.setTime(ClockUtil.getCurrentTime());
      comment.setTaskId(taskId);
      comment.setProcessInstanceId(processInstanceId);
      comment.setAction(Event.ACTION_ADD_ATTACHMENT);
      comment.setMessage(attachmentName);
      commentManager.insert(comment);
    }

    return attachment;
  }
  /** customized insert behavior for HistoricVariableUpdateEventEntity */
  protected void insertHistoricVariableUpdateEntity(
      HistoricVariableUpdateEventEntity historyEvent) {
    DbSqlSession dbSqlSession = getDbSqlSession();

    // insert update only if history level = FULL
    int historyLevel = Context.getProcessEngineConfiguration().getHistoryLevel();
    if (historyLevel == ProcessEngineConfigurationImpl.HISTORYLEVEL_FULL) {

      // insert byte array entity (if applicable)
      byte[] byteValue = historyEvent.getByteValue();
      if (byteValue != null) {
        ByteArrayEntity byteArrayEntity =
            new ByteArrayEntity(historyEvent.getVariableName(), byteValue);
        Context.getCommandContext().getDbSqlSession().insert(byteArrayEntity);
        historyEvent.setByteArrayId(byteArrayEntity.getId());
      }
      dbSqlSession.insert(historyEvent);
    }

    // always insert/update HistoricProcessVariableInstance
    if (HistoryEvent.VARIABLE_EVENT_TYPE_CREATE.equals(historyEvent.getEventType())) {
      HistoricVariableInstanceEntity persistentObject =
          new HistoricVariableInstanceEntity(historyEvent);
      dbSqlSession.insert(persistentObject);

    } else if (HistoryEvent.VARIABLE_EVENT_TYPE_UPDATE.equals(historyEvent.getEventType())) {
      HistoricVariableInstanceEntity historicVariableInstanceEntity =
          dbSqlSession.selectById(
              HistoricVariableInstanceEntity.class, historyEvent.getVariableInstanceId());
      historicVariableInstanceEntity.updateFromEvent(historyEvent);

    } else if (HistoryEvent.VARIABLE_EVENT_TYPE_DELETE.equals(historyEvent.getEventType())) {
      HistoricVariableInstanceEntity historicVariableInstanceEntity =
          dbSqlSession.selectById(
              HistoricVariableInstanceEntity.class, historyEvent.getVariableInstanceId());
      if (historicVariableInstanceEntity != null) {
        historicVariableInstanceEntity.delete();
      }
    }
  }
  /** general history event insert behavior */
  protected void insertOrUpdate(HistoryEvent historyEvent) {

    final DbSqlSession dbSqlSession = getDbSqlSession();

    String eventType = historyEvent.getEventType();
    if (isInitialEvent(eventType)) {
      dbSqlSession.insert(historyEvent);
    } else {
      if (dbSqlSession.findInCache(historyEvent.getClass(), historyEvent.getId()) == null) {
        dbSqlSession.update(historyEvent);
      }
    }
  }