Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

IllegalArgumentException:प्रकार अशक्त नहीं हो सकता

1.11.1 के रूप में स्प्रिंग डेटा जेपीए एसपी को परिणाम सेट लौटाने का समर्थन नहीं करता है। मैंने एक संगत दोष दर्ज किया है स्प्रिंग डेटा के साथ।

समाधान एक एपीआई स्तर नीचे उतरना है और केवल जेपीए का उपयोग करना है। यहाँ एक सामान्य वर्ग है जिसे मैंने लिखा है जो MS SQL SPs के साथ काम करता है।

import com.google.common.base.Strings;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.ParameterMode;
import javax.persistence.Query;
import javax.persistence.StoredProcedureQuery;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StoredProcRepository {

  //region Injected beans (via a RequiredArgsConstructor)
  private final EntityManager em;
  //endregion 

  /**
   * Calls a stored procedure via JPA and retrieves a single implicit result set (in DBs that
   * support them e.g. MS SQL or MySQL). The call is not dependent on a DB dialect. Be
   * aware that large result sets should be paginated and not entirely read to memory. Recreates
   * StoredProcedureQuery instance and its parameters on each call.
   * To execute MS SQL SPs performing multiple queries, SET NOCOUNT ON.
   *
   * @param procedureName stored procedure name, optionally qualified per DB syntax
   * @param resultClass converts (maps) each result set row into instances of resultClass via JPA
   * @param spArgs stored procedure arguments, supplied positionally (optional SP arguments at the
   * end of the list could be omitted)
   * @param <T> class of row instances converted per JPA
   * @return the entire result set
   */
  public <T> List<T> queryViaStoredProc(String procedureName, Class<T> resultClass,
      Object... spArgs) {
    StoredProcedureQuery spq = em.createStoredProcedureQuery(procedureName, resultClass);
    int pos = 0;
    for (Object arg : spArgs) {
      spq.registerStoredProcedureParameter(++pos, arg.getClass(), ParameterMode.IN);
      spq.setParameter(pos, arg);
    }
    return spq.getResultList();
  }

  /**
   * Calls a stored procedure via JPA and retrieves only the top row of a single implicit result
   * set (in DBs that support them e.g. MS SQL or MySQL).
   * Assumes that result set has at least one row.
   * The call is not dependent on a DB dialect.
   * Be aware that large result sets should be paginated and not entirely read to memory.
   * Recreates StoredProcedureQuery instance and its parameters on each call.
   * To execute MS SQL SPs performing multiple queries, SET NOCOUNT ON.
   *
   * @param procedureName stored procedure name, optionally qualified per DB syntax
   * @param resultClass converts (maps) each result set row into instances of resultClass via JPA
   * @param spArgs stored procedure arguments, supplied positionally (optional SP arguments at the
   * end of the list could be omitted)
   * @param <T> class of row instances converted per JPA
   * @return the entire result set
   */
  public <T> T queryTopRowViaStoredProc(String procedureName, Class<T> resultClass,
      Object... spArgs) {
    return queryViaStoredProc(procedureName, resultClass, spArgs).get(0);
  }
}

MS SQL SPs के लिए, अतिरिक्त आवश्यकता SET NOCOUNT ON . है एक से अधिक क्वेरी निष्पादित करने वाले सभी एसपी के लिए। इसे कम से कम तीन तरीकों में से एक में सेट किया जा सकता है:

  1. जेपीए का उपयोग करते हुए एक सामान्य जावा रैपर में (नीचे कोड देखें)। यह दृष्टिकोण केवल jTDS JDBC ड्राइवर के साथ काम करता है। संबंधित समस्या MS JDBC ड्राइवर प्रोजेक्ट के साथ दायर किया गया है।
  2. प्रत्येक एसपी की शुरुआत में।
  3. विश्व स्तर पर आपके डेटाबेस में

उसका # 1 के लिए कोड है:समान StoredProcRepository . के लिए संबंधित विधियाँ कक्षा।

  /**
   * Calls an MS SQL stored procedure via JPA and retrieves a single implicit result set.
   * Protects against lack of SET NOCOUNT in stored procedures.
   * This works with jTDS JDBC driver, but not with MS JDBC driver.
   * Be aware that large result sets should be paginated and not entirely read to memory.
   *
   * @param procedureName stored procedure name, optionally qualified per DB syntax
   * @param resultClass converts (maps) each result set row into instances of resultClass via JPA
   * @param spArgs stored procedure arguments, supplied positionally (optional SP arguments at the
   * end of the list could be omitted)
   * @param <T> class of row instances converted per JPA
   * @return the entire result set
   */
  public <T> List<T> queryViaMsSqlStoredProc(String procedureName, Class<T> resultClass,
      Object... spArgs) {
    String spBindParams = (spArgs.length == 0) ? "" : "?" + Strings.repeat(",?", spArgs.length - 1);

    // The following works with jTDS driver, but not with MS driver
    String spQuery = String.format("EXEC %s %s", procedureName, spBindParams);

    // The following works with jTDS driver, but not with MS driver
    /*
    String spQuery = String.format("{call %s(%s)}", procedureName, spBindParams);
    Query q = em.createNativeQuery("SET NOCOUNT ON; " + spQuery, resultClass)
        .setHint("org.hibernate.readOnly", true);
    */

    Query q = em.createNativeQuery(spQuery, resultClass);
    int pos = 0;
    for (Object arg : spArgs) {
      q.setParameter(++pos, arg);
    }
    return q.getResultList();
  }    

  /**
   * Calls an MS SQL stored procedure via JPA and retrieves only the top row of a single implicit
   * result set.
   * Assumes that result set has at least one row.
   * The call sets the "NOCOUNT ON" MS SQL batch option.
   * Be aware that large result sets should be paginated and not entirely read to memory.
   *
   * @param procedureName stored procedure name, optionally qualified per DB syntax
   * @param resultClass converts (maps) each result set row into instances of resultClass via JPA
   * @param spArgs stored procedure arguments, supplied positionally (optional SP arguments at the
   * end of the list could be omitted)
   * @param <T> class of row instances converted per JPA
   * @return the entire result set
   */
  public <T> T queryTopRowViaMsSqlStoredProc(String procedureName, Class<T> resultClass,
      Object... spArgs) {
    return queryViaMsSqlStoredProc(procedureName, resultClass, spArgs).get(0);
  }


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ubuntu 14.04 पर MySQL 5.5 से 5.6 में अपग्रेड कैसे करें

  2. SQL सर्वर डेटाबेस को MySQL में कैसे निर्यात करें?

  3. AJAX + jQuery + PHP . के साथ MySQL को डेटा भेजें

  4. MacOS सिएरा पर mysql2 रत्न स्थापित नहीं कर सकता

  5. MySQL में टेबल कॉपी कैसे करें