PG / Hibernate:运算符不存在:字符变化= bytea

时间:2017-09-08 17:37:34

标签: postgresql hibernate

我有一个pg查询要在spring batch partionner中执行,具有以下结构

SELECT string_agg(DISTINCT CAST(suivi.it_suivi_solde AS text), ';') AS ids 
FROM T_CPT_C_SUIVI_SOLDE suivi, 
     T_CPT_C_CONSTAT_CREANCE constatcr 
WHERE suivi.co_statut_suivi_solde = 'NTR' 
  AND suivi.dt_limite_paiement  + :delaiMajoration * interval '1 day' < :dateLimitePaiement 
  AND suivi.co_sens_solde = 'D' 
  AND suivi.ID_PROC_DELCTX IS NULL 
  AND (   :listePartGestion IS NULL 
       OR suivi.CO_PARTICULARITE_GESTION  NOT IN (:listePartGestion)) 
  AND suivi.it_suivi_solde = constatcr.it_suivi_solde 
  GROUP BY suivi.IT_MIR, suivi.valeur_echeance_recouvre, suivi.dt_limite_paiement 

HAVING SUM(constatcr.mt_solde)&gt; 0

当我的数据库中有数据时,我也没有例外,我得到了错误:

  

运算符不存在:字符变化= bytea ..

执行查询的分区程序如下:

    @Setter
    @Slf4j
    public class JdbcToFilePartitioner implements Partitioner, InitializingBean {

        @PersistenceContext
        private EntityManager entityManager;
        private int fetchSize = 100;
        private String sqlGetIdToProcess;
        private File workDirStep;
        private Long nbItemMax;

        @Override
        public Map<String, ExecutionContext> partition(final int gridSize) {

            // Création contextes d'execution pour chacune des partitions
            Map<String, ExecutionContext> executionsContexte = createExecutionsContext(gridSize);

            // Alimenter les partitions avec les ids à traiter
            getIdsAndFillPartitionFiles(executionsContexte);

            return executionsContexte;
        }

        /**
         * Création des contextes d'execution pour chaque partition
         * @param gridSize nombre de partition
         * @return map contenant les contextes d'execution
         */
        private Map<String, ExecutionContext> createExecutionsContext(final int gridSize) {

            final Map<String, ExecutionContext> map = new HashMap<>();
            for (int idPartition = 0; idPartition < gridSize; idPartition++) {

                String racineNomPartition = "partition_" + LocalDateTime.now().toString("yyMMdd'_'HHmmssSSS");
                String nomFichier = workDirStep + File.separator + racineNomPartition + "_" + idPartition + ".txt";
                final ExecutionContext context = new ExecutionContext();
                context.put(PartitionerConstantes.ID_GRID.getCode(), idPartition);
                context.put(PartitionerConstantes.FILE_NAME.getCode(), nomFichier);
                map.put(String.valueOf(idPartition), context);
            }
            return map;
        }

        /**
         * Execute la requete de selection des identifiants à traier et rempli les fichiers de partitions de manière equitable
         * @param executionsContext contexte d'execution contenant les noms de fichiers à remplir
         */
        private void getIdsAndFillPartitionFiles(final Map<String, ExecutionContext> executionsContexte) {

            List<BufferedWriter> fileWriters = new ArrayList<>();
            try {

                // Création des BufferedWriter pour chacune des partitions
                for (int i = 0; i < executionsContexte.size(); i++) {
                    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(executionsContexte.get(String.valueOf(i)).getString(
                            PartitionerConstantes.FILE_NAME.getCode())));
                    fileWriters.add(bufferedWriter);
                }

                // Construit le requete
                StatelessSession session = ((Session) entityManager.getDelegate()).getSessionFactory().openStatelessSession();
                Query query = buildQuery(session);

                // Execute la requete
                query.setFetchSize(fetchSize);
                query.setReadOnly(true);
                // query.setLockMode("a", LockMode.NONE);
                ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);

                int currentPartition = 0;
                int nbEcriture = 0;

                while (results.next()) {
                    fileWriters.get(currentPartition).write(results.get(0).toString());
                    fileWriters.get(currentPartition).newLine();
                    currentPartition++;
                    nbEcriture++;

                    if (currentPartition >= executionsContexte.size()) {
                        currentPartition = 0;
                    }

                    if (nbItemMax != null && nbEcriture >= nbItemMax) {
                        break;
                    }
                }

                results.close();
                session.close();
                for (BufferedWriter bufferedWriter : fileWriters) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                throw new UnexpectedJobExecutionException("Erreur d'accès au fichier de partition", e);
            }
        }

        private Query buildQuery(final StatelessSession session) {
            Query query = session.createSQLQuery(sqlGetIdToProcess);

            if (query != null) {

                if (sqlGetIdToProcess.contains(":dateLimitePaiement")) {

                    if (ContexteBatch.getExecution().getJobExecution().getExecutionContext().get("DELAI_TMP_CALC_MAJO") != null) {
                        query.setParameter(
                                "dateLimitePaiement",
                                ContexteBatch
                                        .getDateTraitement()
                                        .dayOfMonth()
                                        .addToCopy(
                                                (Integer) ContexteBatch.getExecution().getJobExecution().getExecutionContext().get("DELAI_TMP_CALC_MAJO"))
                                        .toDate());
                    } else {
                        query.setParameter("dateLimitePaiement", ContexteBatch.getDateTraitement() != null ? ContexteBatch.getDateTraitement().toDate()
                                : new Date());
                    }
                }
                if (sqlGetIdToProcess.contains(":delaiMajoration")) {
                    query.setParameter(
                            "delaiMajoration",
                            ContexteBatch.getParametre("delaiMajoration") != null ? (Integer) ContexteBatch.getParametre("delaiMajoration") : Integer
                                    .valueOf(0));
                }
                if (sqlGetIdToProcess.contains(":listePartGestion")) {
                    query.setParameter("listePartGestion",
                            ContexteBatch.getParametre("listePartGestion") != null ? (List<String>) ContexteBatch.getParametre("listePartGestion") : null);
                }
            } else {
                log.error("La requête est null ");
            }
            log.info(query.toString());
            return query;
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            Assert.notNull(sqlGetIdToProcess, "La requête de partitionnement doit être configurée.");
        }

    }

请知道。 谢谢。

1 个答案:

答案 0 :(得分:1)

解决方案是 CAST AS TEXT listePartGestion运算符

SELECT string_agg(DISTINCT CAST(suivi.it_suivi_solde AS text), ';') AS ids 
FROM T_CPT_C_SUIVI_SOLDE suivi, 
      T_CPT_C_CONSTAT_CREANCE constatcr 
WHERE suivi.co_statut_suivi_solde = 'NTR' 
      AND suivi.dt_limite_paiement  + :delaiMajoration * interval '1 day' < 
        :dateLimitePaiement 
      AND suivi.co_sens_solde = 'D' 
      AND suivi.ID_PROC_DELCTX IS NULL 
      AND ( :listePartGestion IS NULL 
      OR suivi.CO_PARTICULARITE_GESTION  NOT IN (CAST(:listePartGestion AS text))) 
      AND suivi.it_suivi_solde = constatcr.it_suivi_solde 
GROUP BY suivi.IT_MIR, suivi.valeur_echeance_recouvre, suivi.dt_limite_paiement