@Override
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public BuckWaResponse update(BuckWaRequest request) {
    if (logger.isInfoEnabled()) {
      logger.info(this.getClass().toString() + "-update-");
    }
    BuckWaResponse response = new BuckWaResponse();
    try {
      Holiday holiday = (Holiday) request.get("holiday");

      response.setStatus(BuckWaConstants.FAIL);
      if (holiday.getHolidayName().length() < 1) {
        response.setErrorCode("E017");
      } else {
        Holiday oldHoliday = holidayDao.getHolidayById(holiday.getHolidayId());
        boolean isExist = holidayDao.isHolidayExist(holiday);
        boolean isSameYear = oldHoliday.getYearId().equals(holiday.getYearId());
        boolean isSameDate = oldHoliday.getHolidayDate().equals(holiday.getHolidayDate());
        boolean isSameDesc = oldHoliday.getHolidayDesc().equals(holiday.getHolidayDesc());
        boolean isSameName = oldHoliday.getHolidayName().equals(holiday.getHolidayName());
        boolean isSameEnable = oldHoliday.isEnable() == holiday.isEnable();

        boolean isDirty = !(isSameYear && isSameDate && isSameDesc && isSameEnable && isSameName);

        if (!isExist || isDirty) {
          holidayDao.update(holiday);
          response.setSuccessCode("S002");
          response.setStatus(BuckWaConstants.SUCCESS);
        } else {
          response.setErrorCode("E002");
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
      response.setStatus(BuckWaConstants.FAIL);
      response.setErrorCode("E001");
    }

    return response;
  }
  @Override
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public BuckWaResponse create(BuckWaRequest request) {
    if (logger.isInfoEnabled()) {
      logger.info(this.getClass().toString() + "-create-");
    }
    BuckWaResponse response = new BuckWaResponse();
    try {
      HolidayCriteria holidayCriteria = (HolidayCriteria) request.get("holidayCriteria");
      boolean isExist = false;

      if (holidayCriteria != null && holidayCriteria.getHolidayName().length() > 1) {
        DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
        List<Date> listDuration = new ArrayList<Date>();

        if (holidayCriteria.getIsDurationDate().equalsIgnoreCase("true")
            && holidayCriteria.getMinDate() != null
            && holidayCriteria.getMinDate().length() > 0
            && holidayCriteria.getMaxDate() != null
            && holidayCriteria.getMaxDate().length() > 0) {
          if (logger.isInfoEnabled()) {
            logger.info("- duration Date -");
            logger.info("- minDate: " + holidayCriteria.getMinDate());
            logger.info("- maxDate: " + holidayCriteria.getMaxDate());
          }
          /* BEGIN: try from
           * http://stackoverflow.com/questions/2689379/how-to-get-a-list-of-dates-between-two-dates-in-java
           */
          Date startDate = (Date) formatter.parse(holidayCriteria.getMinDate());
          Date endDate = (Date) formatter.parse(holidayCriteria.getMaxDate());
          long interval = 24 * 1000 * 60 * 60; // 1 Day in millis
          long endTime =
              endDate.getTime(); // create your endtime here, possibly using Calendar or Date
          long curTime = startDate.getTime();
          while (curTime <= endTime) {
            listDuration.add(new Date(curTime));
            curTime += interval;
          }

          /* END: try */
        } else if (!holidayCriteria.getIsDurationDate().equalsIgnoreCase("true")
            && holidayCriteria.getHolidayDate() != null
            && holidayCriteria.getHolidayDate().length() > 0) {
          if (logger.isInfoEnabled()) {
            logger.info("- singleDate: " + holidayCriteria.getHolidayDate());
          }
          listDuration.add((Date) formatter.parse(holidayCriteria.getHolidayDate()));
        } else {
          throw new Exception("Something Abnormal!");
        }

        if (logger.isInfoEnabled()) {
          for (int i = 0; i < listDuration.size(); i++) {
            Date lDate = (Date) listDuration.get(i);
            String ds = formatter.format(lDate);
            logger.info(" Date is ..." + ds);
          }
        }

        for (int i = 0; i < listDuration.size(); i++) {
          Holiday holiday = new Holiday();

          holiday.setYearId(holidayCriteria.getYearId());
          holiday.setHolidayDate(formatter.format(listDuration.get(i)));
          holiday.setHolidayName(holidayCriteria.getHolidayName());
          holiday.setHolidayDesc(holidayCriteria.getHolidayDesc());

          isExist = holidayDao.isHolidayExist(holiday);

          if (isExist) {
            response.setErrorCode("E002");
            response.setStatus(BuckWaConstants.FAIL);
            break;
          }
        }

        if (!isExist) {

          for (int i = 0; i < listDuration.size(); i++) {
            Holiday holiday = new Holiday();

            holiday.setYearId(holidayCriteria.getYearId());
            holiday.setHolidayDate(formatter.format(listDuration.get(i)));
            holiday.setHolidayName(holidayCriteria.getHolidayName());
            holiday.setHolidayDesc(holidayCriteria.getHolidayDesc());
            holiday.setEnable(holidayCriteria.isEnable());

            holidayDao.create(holiday);
          }

          response.setSuccessCode("S001");
        }

      } else {
        response.setErrorCode("E017");
        response.setStatus(BuckWaConstants.FAIL);
      }

    } catch (DuplicateKeyException dx) {
      response.setStatus(BuckWaConstants.FAIL);
      response.setErrorCode("E002");
    } catch (Exception ex) {
      ex.printStackTrace();
      if (ex.getMessage().equals("Something Abnormal!")) {
        response.setErrorCode("E017");
      } else {
        response.setErrorCode("E001");
      }
      response.setStatus(BuckWaConstants.FAIL);
    }

    // Success return S001
    response.setSuccessCode("S001");
    return response;
  }