for循环中的对象不保存

时间:2015-12-07 18:38:23

标签: grails gorm

我有一个小批量上传工作,我正在迭代抛出一个CSV文件并创建对象并使用grails gorm保存它们。如果csv文件中的记录有任何失败,我会跳过记录并继续下一步。我发现如果没有使用withNewTransaction将我的保存包装在新的事务中,我无法保存任何对象。我认为这是解决实际问题的黑客行为。我想知道是否有人能够帮助我理解这里发生的事情。

控制器

dim emailreceiver as string

emailreceiver = '(the new object I created that called the function, in this case it is "assignmsg").msgto

BatchUploadService

def uploadFile() {      
    def division = params.division;

    userService.requireRole(division)

    MultipartFile file = request.getFile('file');

    if(file.empty) {
        flash.message = "File cannot be empty"          
    } else {
        def effortDetailMap = batchUploadService.processBatch(file, division);                  

        flash.success = effortDetailMap['Success'].size() + " new records were successfully added.";
        flash.failed = effortDetailMap['Failed'].size() + " records failed to be added.";
        flash.filtered = effortDetailMap['Filtered'].size() + " records were filtered.";

        batchUploadService.excelOutput(effortDetailMap);            
    }
    redirect (action:'upload', params: [division: params.division])
}

RecoveryDetailService

def populateBean(file) {
    CsvToBean<EffortDetail> csvToBean = new CsvToBean<>();

    Map<String, String> columnMapping = new HashMap<String, String>();
    columnMapping.put("ITEM_NO", "alternateId");
    columnMapping.put("FIRST_NAME", "firstName");
    columnMapping.put("LAST_NAME", "lastName");
    columnMapping.put("TASK_CODE", "orgkey");
    columnMapping.put("PAY_END_DATE", "expenseDate");
    columnMapping.put("TOT_TDS_TIME", "projectHours");
    columnMapping.put("411 TOTAL", "totalHours");

    HeaderColumnNameTranslateMappingStrategy<EffortDetail> strategy = new HeaderColumnNameTranslateMappingStrategy<EffortDetail>();
    strategy.setType(EffortDetail.class);
    strategy.setColumnMapping(columnMapping);

    Reader reader = new InputStreamReader(file.getInputStream());

    CustomReader csvReader = new CustomReader(reader, (char) '|', CSVWriter.NO_QUOTE_CHARACTER);

    return csvToBean.parse(strategy, csvReader);
}

def processBatch(file, division) {
    def effortDetails = populateBean(file)

    def effortDetailMap = [:]
    effortDetailMap["Success"] = []
    effortDetailMap["Failed"] = []
    effortDetailMap["Filtered"] = []

    for (def effortDetail in effortDetails) {
        String orgKey = effortDetail.getOrgkey();

        if (orgKey.matches("\\d{6}") || orgKey.matches("\\d{6} HRI")) {
            effortDetail.setOrgkey(orgKey.substring(0, 6));
        } else {
            effortDetailMap['Filtered'] << effortDetail;
            continue;
        }

        effortDetail.setDivision(division)
        effortDetail.setPkDivision(effortDetail.getDivision());
        effortDetail.setPkOrgkey(effortDetail.getOrgkey());

        try {
            if(effortDetail.getTotalHours() == null || effortDetail.getTotalHours().isEmpty()) {
                throw new NullPointerException("Invalid Total Hours");
            } else if(new BigDecimal(effortDetail.getTotalHours()).compareTo(new BigDecimal(75)) < 0) {
                effortDetail.setTotalHours("75");
            }

            if(effortDetail.getProjectHours() == null || effortDetail.getProjectHours().isEmpty()) {
                throw new NullPointerException("Invalid Project Hours");
            }

            RecoveryDetail recoveryDetail = recoveryDetailService.fill(effortDetail);

            if(!recoveryDetail.validate()) {
                def errors = new StringBuilder()

                recoveryDetail.errors.each {errors.append(it)}

                throw new Exception(errors);
            }

            RecoveryDetail.withNewTransaction {TransactionStatus status ->
                try {
                  recoveryDetail.save(failOnError: true)
                } catch (ex) {
                  status.setRollbackOnly()
                }
            }

            effortDetailMap['Success'] << effortDetail
        } catch(Exception ex) {
            effortDetail.failure = ex.message;
            effortDetailMap['Failed'] << effortDetail
        }
    }

    return effortDetailMap
}

0 个答案:

没有答案