Почему запрос CTE не работает в Hibernate?

Это мой запрос CTE

String query = "WITH Search(id, name, merchantId, merchantName,merchantNo, purpose, maxDate, paymentAmount) AS (SELECT PAS.GATEWAY_ID AS id, (SELECT NAME FROM GATEWAY_DETAILS WHERE GATEWAY_ID=(SELECT GATEWAY_ID FROM GATEWAY WHERE GATEWAY_ID=PAS.GATEWAY_ID)) AS NAME, PD.merchantName_ID, (SELECT merchantName_NAME FROM merchantName_MASTER WHERE merchantName_ID=PD.merchantName_ID) AS merchantName, PD.TXN_NO, (SELECT MERCHANT_DESC FROM MERCHANTS WHERE DESC_ID=PAS.DESC_ID) AS PURPOSE, PD.TXN_DATE AS maxDate,CHEQUE_AMOUNT FROM TXN_DETAILS PD INNER JOIN GATEWAY_PASS PAS ON PD.PMNT_TXN_ID=PAS.PMNT_TXN_ID WHERE  PD.TXN_DATE  BETWEEN '2016/10/28' AND '2016/12/28' AND PD.GATEWAY_ID=PAS.GATEWAY_ID), MaxDate1(id1, MAX_DATE) AS (SELECT PD.GATEWAY_ID, MAX(maxDate) AS MAX_DATE FROM TXN_DETAILS PD, Search SMD WHERE GATEWAY_ID IN(SELECT id FROM Search) GROUP BY PD.GATEWAY_ID), MaxDate2(id1, MAX_DATE) AS ( SELECT PD.GATEWAY_ID, MAX(PD.TXN_DATE) FROM TXN_DETAILS PD, Search SMD WHERE PD.GATEWAY_ID IN(SMD.id) GROUP BY PD.GATEWAY_ID ), TxnDetails(GATEWAY1,  txnDate1, GATEWAY2, txnDate2) AS (  SELECT MD1.id1,MD2.id1,MD1.MAX_DATE, MD2.MAX_DATE FROM MaxDate1 MD1  INNER JOIN  MaxDate2 MD2 ON MD1.id1=MD2.id1 WHERE MD1.MAX_DATE=MD2.MAX_DATE ) SELECT PD.GATEWAY_ID, (SELECT NAME FROM GATEWAY_DETAILS    WHERE GATEWAY_ID=(SELECT GATEWAY_ID FROM GATEWAY WHERE GATEWAY_ID=PD.GATEWAY_ID)) AS NAME,  (SELECT merchantName_NAME FROM merchantName_MASTER WHERE merchantName_ID=PD.merchantName_ID) AS merchantName_NAME,  PD.TXN_NO, PD.TXN_DATE, PD.CHEQUE_AMOUNT,   (SELECT DESC_ID FROM MERCHANTS WHERE DESC_ID IN (SELECT DESC_ID FROM GATEWAY_PASS WHERE PMNT_TXN_ID=PD.PMNT_TXN_ID)) AS DESC_ID ,    (SELECT MERCHANT_DESC FROM MERCHANTS WHERE DESC_ID IN (SELECT DESC_ID FROM GATEWAY_PASS WHERE PMNT_TXN_ID=PD.PMNT_TXN_ID)) AS PURPOSE , PD.TXN_DATE FROM TXN_DETAILS PD WHERE PD.GATEWAY_ID IN (SELECT GATEWAY1 FROM TxnDetails) AND PD.TXN_DATE IN (SELECT txnDate2 FROM TxnDetails)";

это ДАО

  List<Object[]> ObjList = entityManager.createNativeQuery(query).getResultList();
            List<TxntxnDTO> txnDtoList = new ArrayList();

            for (Object[] object : ObjList) {
                TxnDTO txnDTO = new TxnDTO();
                txnDTO.setid((String) object[0]);
                txnDTO.setname((String) object[1]);
                txnDTO.setmerchantNameName((String) object[2]);
                txnDTO.setmerchantNo((String) object[3]);
                txnDTO.setTxnDate((Date) object[4]);
                txnDTO.setTxnAmount((BigDecimal) object[5]);
                txnDTO.setMerchantId((Integer) object[6]);
                txnDTO.setTxnDesc((String) object[7]);

                txnDtoList.add(txnDTO);
            }

Запрос работает нормально в SQL, но выдает ошибку в DAO

javax.persistence.PersistenceException: org.hibernate.MappingException: нет сопоставления диалектов для типа JDBC: -9


person Sharat Pradhan    schedule 03.02.2017    source источник
comment
Предлагаю, попробовать изменить его в обычном запросе.   -  person Vijunav Vastivch    schedule 03.02.2017
comment
Привет, красные, нормальный запрос работает нормально. Но у меня есть требование сравнивать результаты одного запроса с другим, поэтому я иду на CTE.   -  person Sharat Pradhan    schedule 03.02.2017
comment
Вы указали диалект в свойствах спящего режима? Предоставьте блок конфигурации источника данных   -  person Andremoniy    schedule 13.02.2017
comment
Тип JDBC -9 равен java.sql.Types.NVARCHAR. Похоже, это указывает на то, что ваш диалект Hibernate не обеспечивает сопоставление для этого типа. Убедитесь, что вы используете правильный диалект (для NVARCHAR требуется SQLServer2008Dialect или выше)   -  person Mark Rotteveel    schedule 10.05.2017


Ответы (2)


Мне удалось обойти эту проблему, приведя возвращаемые объекты:

SELECT CAST(field AS VARCHAR(20)) AS field

Из https://stackoverflow.com/a/12986024/2454665 кажется, что иногда база данных возвращает результаты пользовательских запросов SQL в странных типах, которые не могут быть сопоставлены с типами Hibernate, поэтому CAST.

person Nicolas C    schedule 14.02.2017
comment
Спасибо @Николас. Ваше решение работает нормально, но я нашел обходной путь, добавив sqlQuery.addScalar(paymentAmount, BigDecimalType.INSTANCE); - person Sharat Pradhan; 10.05.2017
comment
-9 не странный тип, это Types.NVARCHAR. - person Mark Rotteveel; 10.05.2017
comment
Привет, Марк, за это время я искал, но не смог найти решения этой проблемы. - person Sharat Pradhan; 11.05.2017

Я решил эту проблему, следуя

Это мой класс DTO

    public class PaymentPostingDTO {

    private String id;

    private String name;

    private String merchantId;

    private String merchantName;

    private Integer merchantNo;

    private String purpose;

    private Date maxDate;

    private BigDecimal paymentAmount;

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the merchantId
     */
    public String getMerchantId() {
        return merchantId;
    }

    /**
     * @param merchantId
     *            the merchantId to set
     */
    public void setMerchantId(String merchantId) {
        this.merchantId = merchantId;
    }

    /**
     * @return the merchantName
     */
    public String getMerchantName() {
        return merchantName;
    }

    /**
     * @param merchantName
     *            the merchantName to set
     */
    public void setMerchantName(String merchantName) {
        this.merchantName = merchantName;
    }

    /**
     * @return the merchantNo
     */
    public Integer getMerchantNo() {
        return merchantNo;
    }

    /**
     * @param merchantNo
     *            the merchantNo to set
     */
    public void setMerchantNo(Integer merchantNo) {
        this.merchantNo = merchantNo;
    }

    /**
     * @return the purpose
     */
    public String getPurpose() {
        return purpose;
    }

    /**
     * @param purpose
     *            the purpose to set
     */
    public void setPurpose(String purpose) {
        this.purpose = purpose;
    }

    /**
     * @return the maxDate
     */
    public Date getMaxDate() {
        return maxDate;
    }

    /**
     * @param maxDate
     *            the maxDate to set
     */
    public void setMaxDate(Date maxDate) {
        this.maxDate = maxDate;
    }

    /**
     * @return the paymentAmount
     */
    public BigDecimal getPaymentAmount() {
        return paymentAmount;
    }

    /**
     * @param paymentAmount
     *            the paymentAmount to set
     */
    public void setPaymentAmount(BigDecimal paymentAmount) {
        this.paymentAmount = paymentAmount;
    }

}

Это моя реализация DAO

      Session session = getHibernateSession();
                String query = "WITH Search(id, name, merchantId, merchantName,merchantNo, purpose, maxDate, paymentAmount) AS 
        (
        SELECT PAS.GATEWAY_ID AS id, (SELECT NAME FROM GATEWAY_DETAILS WHERE GATEWAY_ID=(SELECT GATEWAY_ID FROM GATEWAY WHERE GATEWAY_ID=PAS.GATEWAY_ID)) AS NAME, PD.merchantName_ID, (SELECT merchantName_NAME FROM merchantName_MASTER WHERE merchantName_ID=PD.merchantName_ID) AS merchantName, PD.TXN_NO, (SELECT MERCHANT_DESC FROM MERCHANTS WHERE DESC_ID=PAS.DESC_ID) AS PURPOSE, PD.TXN_DATE AS maxDate,CHEQUE_AMOUNT FROM TXN_DETAILS PD INNER JOIN GATEWAY_PASS PAS ON PD.PMNT_TXN_ID=PAS.PMNT_TXN_ID WHERE  PD.TXN_DATE  BETWEEN '2016/10/28' AND '2016/12/28' AND PD.GATEWAY_ID=PAS.GATEWAY_ID), MaxDate1(id1, MAX_DATE) AS (SELECT PD.GATEWAY_ID, MAX(maxDate) AS MAX_DATE FROM TXN_DETAILS PD, Search SMD WHERE GATEWAY_ID IN(SELECT id FROM Search) GROUP BY PD.GATEWAY_ID), MaxDate2(id1, MAX_DATE) AS ( SELECT PD.GATEWAY_ID, MAX(PD.TXN_DATE) FROM TXN_DETAILS PD, Search SMD WHERE PD.GATEWAY_ID IN(SMD.id) GROUP BY PD.GATEWAY_ID ), TxnDetails(GATEWAY1,  txnDate1, GATEWAY2, txnDate2) AS (  SELECT MD1.id1,MD2.id1,MD1.MAX_DATE, MD2.MAX_DATE FROM MaxDate1 MD1  INNER JOIN  MaxDate2 MD2 ON MD1.id1=MD2.id1 WHERE MD1.MAX_DATE=MD2.MAX_DATE ) SELECT PD.GATEWAY_ID, (SELECT NAME FROM GATEWAY_DETAILS    WHERE GATEWAY_ID=(SELECT GATEWAY_ID FROM GATEWAY WHERE GATEWAY_ID=PD.GATEWAY_ID)) AS NAME,  (SELECT merchantName_NAME FROM merchantName_MASTER WHERE merchantName_ID=PD.merchantName_ID) AS merchantName_NAME,  PD.TXN_NO, PD.TXN_DATE, PD.CHEQUE_AMOUNT,   (SELECT DESC_ID FROM MERCHANTS WHERE DESC_ID IN (SELECT DESC_ID FROM GATEWAY_PASS WHERE PMNT_TXN_ID=PD.PMNT_TXN_ID)) AS DESC_ID ,    (SELECT MERCHANT_DESC FROM MERCHANTS WHERE DESC_ID IN (SELECT DESC_ID FROM GATEWAY_PASS WHERE PMNT_TXN_ID=PD.PMNT_TXN_ID)) AS PURPOSE , PD.TXN_DATE FROM TXN_DETAILS PD WHERE PD.GATEWAY_ID IN (SELECT GATEWAY1 FROM TxnDetails) AND PD.TXN_DATE IN (SELECT txnDate2 FROM TxnDetails
        )";

        SQLQuery sqlQuery = session.createSQLQuery(query);
        sqlQuery.addScalar("id", StringType.INSTANCE);
        sqlQuery.addScalar("name", StringType.INSTANCE);
        sqlQuery.addScalar("merchantId", StringType.INSTANCE);
        sqlQuery.addScalar("merchantName", StringType.INSTANCE);
        sqlQuery.addScalar("merchantNo", IntegerType.INSTANCE);
        sqlQuery.addScalar("purpose", StringType.INSTANCE);
        sqlQuery.addScalar("maxDate", DateType.INSTANCE);
        sqlQuery.addScalar("paymentAmount", BigDecimalType.INSTANCE);
  sqlQuery.setResultTransformer(Transformers.aliasToBean(PaymentPostingDTO.class));
    List<PaymentPostingDTO> paymentList = sqlQuery.list();
person Sharat Pradhan    schedule 10.05.2017