【问题标题】:PG/Hibernate : operator does not exist: character varying = byteaPG/Hibernate:运算符不存在:字符变化 = bytea
【发布时间】:2018-02-17 16:46:31
【问题描述】:

我有一个pg查询要在spring批处理partner中执行,结构如下

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 

总和(constatcr.mt_solde) > 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.");
        }

    }

请有任何想法。 谢谢。

【问题讨论】:

  • 向我们展示执行该 SQL 的 Java 代码 - 尤其是传递给 PreparedStatement 的参数。另外:dt_limite_paiementCO_PARTICULARITE_GESTION 列的数据类型是什么?
  • 谢谢你的回答,我已经用java类更新了我的问题
  • 解决方法是将listePartGestion操作符CAST AS TEXT
  • 对我来说,这是由于为字符串类型的 where 参数传递了空值

标签: postgresql hibernate


【解决方案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 

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 2016-02-28
    • 2021-01-06
    • 2020-03-19
    • 1970-01-01
    • 2017-06-23
    • 2021-11-15
    相关资源
    最近更新 更多