Hibernate无法执行本机查询SqlExceptionHelper:参数“parameterIndex”

时间:2017-08-03 05:10:54

标签: java spring hibernate spring-boot h2

我有本机SQL请求,它由两个

组成
  • insert - select(with subrequest)
  • 选择

该参数是三个String元素的列表,并传递给:

@Modifying
@Query(value = " "
//close
+ "INSERT INTO status (is_open,advertisement, updated) "
+ "SELECT "
+ " false, to_close.id, NOW() "
+ "FROM( "
+ " SELECT " 
+ "             ad.id as id, " 
+ "             ad.native_id as native_id, " 
+ "             sc_newest.updated as updated, " 
+ "             status.is_open as is_open " 
+ " FROM advertisement AS ad " 
+ " LEFT JOIN " 
+ "         (SELECT "
+ "             MAX(sc.UPDATED) AS updated, "
+ "             sc.ADVERTISEMENT "
+ "         FROM ADVERTISEMENT AS ad "
+ "         LEFT JOIN STATUS AS sc "
+ "             ON  ad.ID = sc.ADVERTISEMENT "
+ "         WHERE   ad.NATIVE_ID NOT IN  :shown_ads "
+ "         GROUP BY sc.advertisement) AS sc_newest "
+ "     ON ad.id = sc_newest.advertisement "
+ " LEFT JOIN status AS status "
+ "     ON ad.id = status.advertisement AND status.updated = sc_newest.updated "
+ " WHERE "
+ "     status.is_open = true " 
+ "     AND ad.native_id NOT IN :shown_ads) AS to_close ; "
+ ""
// get stored previously 
+ " SELECT "
+ " ADVERTISEMENT.NATIVE_ID "
+ "FROM ADVERTISEMENT "
+ " WHERE "
+ " ADVERTISEMENT.NATIVE_ID IN :shown_ads "
        , nativeQuery = true)
public Set<String> closeReopenFindStored(@Param("shown_ads") List<String> shownNaturalIDs);

这里是日志

  

2017-08-03 07:44:12.353 DEBUG 16162 --- [主要]   org.hibernate.SQL:

     

INSERT INTO状态(is_open,广告,更新)SELECT false,   to_close.id,NOW()FROM(SELECT ad.id as id,ad.native_id as   native_id,sc_newest.updated as updated,status.is_open as   is_open FROM广告AS ad LEFT JOIN(选择                 MAX(sc.UPDATED)AS已更新,sc.ADVERTISEMENT FROM ADVERTISEMENT as ad LEFT JOIN STATUS as sc ON ad.ID =   sc.ADVERTISEMENT在哪里ad.NATIVE_ID不在(?,?,?)GROUP BY   sc.advertisement)AS sc_newest ON ad.id = sc_newest.advertisement     LEFT JOIN状态AS状态ON ad.id = status.advertisement AND   status.updated = sc_newest.updated WHERE status.is_open = true         AND ad.native_id NOT IN(?,?,?))AS to_close;选择     ADVERTISEMENT.NATIVE_ID来自广告     ADVERTISEMENT.NATIVE_ID IN(?,?,?)

     

2017-08-03 07:44:12.429 TRACE 16162 --- [主要]   o.h.type.descriptor.sql.BasicBinder:绑定参数[1]为   [VARCHAR] - [ad1号码] 2017-08-03 07:44:12.430 TRACE 16162 --- [
  main] o.h.type.descriptor.sql.BasicBinder:绑定参数[4]   as [VARCHAR] - [ad1 number] 2017-08-03 07:44:12.431 TRACE 16162 --- [   main] o.h.type.descriptor.sql.BasicBinder:绑定参数[7]   as [VARCHAR] - [ad1 number]

     

2017-08-03 07:44:12.432 WARN 16162 --- [主要]   o.h.engine.jdbc.spi.SqlExceptionHelper:SQL错误:90008,SQLState:   90008 2017-08-03 07:44:12.433错误16162 --- [主要]   o.h.engine.jdbc.spi.SqlExceptionHelper:无效值“7”表示   参数“parameterIndex”[90008-195]

为什么这不起作用?

更新 - SQL我从SQL客户端运行良好:

INSERT INTO status (is_open,advertisement, updated) 
SELECT 
    false, to_close.id, NOW() 
FROM( 
    SELECT 
                ad.id as id, 
                ad.native_id as native_id, 
                sc_newest.updated as updated, 
                status.is_open as is_open 
    FROM advertisement AS ad 
    LEFT JOIN 
            (SELECT 
                MAX(sc.UPDATED) AS updated, 
                sc.ADVERTISEMENT 
            FROM ADVERTISEMENT AS ad 
            LEFT JOIN STATUS AS sc 
                ON  ad.ID = sc.ADVERTISEMENT 
            WHERE   ad.NATIVE_ID NOT IN  ('ad1 number','ad2 number', 'new ad') 
            GROUP BY sc.advertisement) AS sc_newest 
        ON ad.id = sc_newest.advertisement 
    LEFT JOIN status AS status 
        ON ad.id = status.advertisement AND status.updated = sc_newest.updated 
    WHERE 
        status.is_open = true 
        AND ad.native_id NOT IN ('ad1 number','ad2 number', 'new ad')) AS to_close ; 


SELECT 
    ADVERTISEMENT.ID AS ad_id,
    ADVERTISEMENT.NATIVE_ID
FROM ADVERTISEMENT
WHERE
    ADVERTISEMENT.NATIVE_ID IN ('ad1 number','ad2 number', 'new ad')

1 个答案:

答案 0 :(得分:1)

我已经完成了你的代码,我已经找到了你的问题。问题是你不能运行2个查询,即insert and select查询使用相同的方法,因为你的插入查询和选择查询返回类型不相同所以你必须创建2个不同的方法第一个用于保存数据和第二个用于选择来自数据库的数据。你必须修改你的代码,如下所示

<强> AdvertisementRepository.java

//  @Modifying
    @Query(value = " "
    //close
//  + "INSERT INTO status (is_open,advertisement, updated) "
//  + "SELECT "
//  + " false, to_close.id, NOW() "
//  + "FROM( "
//  + " SELECT " 
//  + "             ad.id as id, " 
//  + "             ad.native_id as native_id, " 
//  + "             sc_newest.updated as updated, " 
//  + "             status.is_open as is_open " 
//  + " FROM advertisement AS ad " 
//  + " LEFT JOIN " 
//  + "         (SELECT "
//  + "             MAX(sc.UPDATED) AS updated, "
//  + "             sc.ADVERTISEMENT "
//  + "         FROM ADVERTISEMENT AS ad "
//  + "         LEFT JOIN STATUS AS sc "
//  + "             ON  ad.ID = sc.ADVERTISEMENT "
//  + "         WHERE   ad.NATIVE_ID NOT IN  :shown_ads "
//  + "         GROUP BY sc.advertisement) AS sc_newest "
//  + "     ON ad.id = sc_newest.advertisement "
//  + " LEFT JOIN status AS status "
//  + "     ON ad.id = status.advertisement AND status.updated = sc_newest.updated "
//  + " WHERE "
//  + "     status.is_open = true " 
//  + "     AND ad.native_id NOT IN :shown_ads) AS to_close ; "
//  + ""
    //reopen
//  + "INSERT INTO status (is_open,advertisement, updated) "
//  + "SELECT "
//  + " true, to_reopen.id, NOW() "
//  + "FROM( "
//  + " SELECT " 
//  + "             ad.id as id, " 
//  + " FROM advertisement AS ad " 
//  + " LEFT JOIN " 
//  + "             (SELECT "
//  + "                 MAX(sc.updated) AS updated, " 
//  + "                 sc.advertisement " 
//  + "             FROM status AS sc "
//  + "             GROUP BY sc.advertisement) AS sc_newest "
//  + "     ON ad.id = sc_newest.advertisement "
//  + " LEFT JOIN status AS status "
//  + "     ON ad.id = status.advertisement AND status.updated = sc_newest.updated "
//  + " WHERE "
//  + "     status.is_open = false " //reopen closed 
//  + "     AND ad.native_id NOT IN :shown_ads) AS to_reopen ; "
//  + ""
    // get stored previously 
    + " SELECT "
    + " advertisement.native_id "
    + "FROM advertisement "
    + " WHERE "
    + " advertisement.native_id IN :shown_ads "
            , nativeQuery = true)

    public List<String> closeReopenFindStored(@Param("shown_ads") List<String> shownNaturalIDs);


    @Modifying
    @Query(value = "INSERT INTO status (is_open,advertisement, updated) "
    + "SELECT "
    + " false, to_close.id, NOW() "
    + "FROM( "
    + " SELECT " 
    + "             ad.id as id, " 
    + "             ad.native_id as native_id, " 
    + "             sc_newest.updated as updated, " 
    + "             status.is_open as is_open " 
    + " FROM advertisement AS ad " 
    + " LEFT JOIN " 
    + "         (SELECT "
    + "             MAX(sc.UPDATED) AS updated, "
    + "             sc.ADVERTISEMENT "
    + "         FROM ADVERTISEMENT AS ad "
    + "         LEFT JOIN STATUS AS sc "
    + "             ON  ad.ID = sc.ADVERTISEMENT "
    + "         WHERE   ad.NATIVE_ID NOT IN  :shown_ads "
    + "         GROUP BY sc.advertisement) AS sc_newest "
    + "     ON ad.id = sc_newest.advertisement "
    + " LEFT JOIN status AS status "
    + "     ON ad.id = status.advertisement AND status.updated = sc_newest.updated "
    + " WHERE "
    + "     status.is_open = true " 
    + "     AND ad.native_id NOT IN :shown_ads) AS to_close ; "
    + "", nativeQuery = true)
    public void saveCloseReopenFindStored(@Param("shown_ads") List<String> shownNaturalIDs);

<强> AdvertisementRepositoryTestService.java

@Transactional
    public List<String> closeReopenFindStored(List<String> shownAdNumbers){
        advertisementRepository.saveCloseReopenFindStored(shownAdNumbers);
        return advertisementRepository.closeReopenFindStored(shownAdNumbers);
    }

<强> AdvertisementRepositoryTest.java

List<String>  storedPreviously =     
                    advertisementRepositoryTestService.closeReopenFindStored(shownAdNaturalIds);
            assertEquals(2, storedPreviously.size());

AdvertisementRepositoryTest.java

没有变化

注意:我已将您的退货类型Set<String>更改为List<String>,您可以根据自己的要求进行更改。