参数绑定的名称不能为空!对于命名参数,您需要在Java版本上使用@Param来查询方法参数。

32

这个问题之前已经发布过了,但我的问题有点不同。以下是相关的JPQL查询:

@Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, "
            + "po.due_date, po_part.id, po_part.part_quantity, "
            + "part.id, part.part_number, part.part_description, "
            + "part.plasma_hrs_per_part, part.grind_hrs_per_part, "
            + "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
            + "FROM Po po "
            + "LEFT JOIN po.partList po_part "
            + "LEFT JOIN po_part.part part "
            + "LEFT JOIN po_part.part where po.id = :id")
    List<ShopOrder> getShopOrder(long id);

现在我尝试执行:

@Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, "
            + "po.due_date, po_part.id, po_part.part_quantity, "
            + "part.id, part.part_number, part.part_description, "
            + "part.plasma_hrs_per_part, part.grind_hrs_per_part, "
            + "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
            + "FROM Po po "
            + "LEFT JOIN po.partList po_part "
            + "LEFT JOIN po_part.part part "
            + "LEFT JOIN po_part.part where po.id = :id")
    List<ShopOrder> getShopOrder(@Param(value="id"));

但这给了我一个警告:

    [ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].  
 [dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in 
 context with path [] threw exception [Request processing failed; nested   
 exception is org.springframework.dao.InvalidDataAccessApiUsageException: 
 Name for parameter binding must not be null or empty! For named parameters 
 you need to use @Param for query method parameters on Java versions < 8.; 
 nested exception is java.lang.IllegalArgumentException: Name for parameter 
 binding must not be null or empty! For named parameters you need to use 
 @Param for query method parameters on Java versions < 8.] with root cause
java.lang.IllegalArgumentException: Name for parameter binding must not be 
null or empty! For named parameters you need to use @Param for query method   
parameters on Java versions < 8.

执行查询的方法是:

 /**
     * Generate Shop Orders.
     */
    @RequestMapping(value = "/generateShopOrder/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public void generate(@PathVariable Long id) throws URISyntaxException {
        System.out.println("po id to generate = " + id);

        List<ShopOrder> shopOrders = po_partRepository.getShopOrder(id);

        for(ShopOrder order: shopOrders) {
            System.out.println("-------Printing Shop Orders" + order);
        }

    }

有何建议?

------------更新----------------

这似乎解决了问题:

@Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, "
            + "po.due_date, po_part.id, po_part.part_quantity, "
            + "part.id, part.part_number, part.part_description, "
            + "part.plasma_hrs_per_part, part.grind_hrs_per_part, "
            + "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
            + "FROM Po po "
            + "LEFT JOIN po.partList po_part "
            + "LEFT JOIN po_part.part part "
            + "LEFT JOIN po_part.part where po.id = ?1")
    List<ShopOrder> getShopOrder(Long id);

但是现在我遇到了一个错误,错误信息如下:

[ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].
[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in 
context with path [] threw exception [Request processing failed; nested 
exception is org.springframework.dao.InvalidDataAccessApiUsageException: 
org.hibernate.QueryException: could not instantiate class 
[com.htd.domain.ShopOrder] from tuple; nested exception is 
java.lang.IllegalArgumentException: org.hibernate.QueryException: could not 
instantiate class [com.htd.domain.ShopOrder] from tuple] with root cause
java.lang.IllegalArgumentException: null

购物订单:

public ShopOrder(long po_id, String po_number, LocalDate po_due_date,
    long po_part_id, int part_quantity, long part_id,
    String part_number, String part_decription, BigDecimal plasma_hrs,
    BigDecimal grind_hours, BigDecimal mill_hrs,
    BigDecimal breakpress_hrs) {

        this.po_id = po_id;
        this.po_number = po_number;
        this.po_due_date = po_due_date;
        this.po_part_id = po_part_id;
        this.part_quantity = part_quantity;
        this.part_id = part_id;
        this.part_number = part_number;
        this.part_decription = part_decription;
        this.plasma_hrs = plasma_hrs;
        this.grind_hours = grind_hours;
        this.mill_hrs = mill_hrs;
        this.breakpress_hrs = breakpress_hrs;

    }

数据库表


@NeilStockton 看到更新了... - Mike3355
所以也许没有ShopOrder的构造函数...检查类型。 - Neil Stockton
@NeilStockton 不是的,现在有了(我刚刚添加了它),但我开始觉得我的查询中的“new”并没有做我想象中的那样。我以为它会创建一个新的ShopOrder实例。我正确吗? - Mike3355
你说的“新实例”是什么意思?如果构造函数存在,你执行一个查询,它会创建一个对象并将其返回给你。 - Neil Stockton
@NeilStockton 是的,那就是我所假设的,而且我已经发布了一个构造函数。 - Mike3355
显示剩余2条评论
3个回答

85

尝试使用此参数描述:

List<ShopOrder> getShopOrder(@Param("id") long id);

8
我觉得很奇怪,JPA不允许在没有值的情况下使用@Param标签,以使用与变量名相同的默认参数名称。 - Amrinder Arora
3
@AmrinderArora 因为变量名不可访问。 - er-han
1
@er-han 是的,但它肯定是可以的。例如:https://dev59.com/0ek6XIcBkEYKwwoYAfG1?noredirect=1&lq=1 - Amrinder Arora
@AmrinderArora 是的,确实如此。感谢您提供这个例子。您是正确的,可以使用“-parameters”编译器标志来完成。我已经找到了这个:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters - er-han
@AmrinderArora 你是对的,-parameters也可以解决这个问题。 - RoutesMaps.com

26

不要使用 : id = : id,而应该使用 ? 1....

@Query("SELECT NEW com.htd.domain.ShopOrder(po.id, po.po_number, "
             + "po.due_date, po_part.id, po_part.part_quantity, "
            + "part.id, part.part_number, part.part_description, "
            + "part.plasma_hrs_per_part, part.grind_hrs_per_part, "
            + "part.mill_hrs_per_part, part.brakepress_hrs_per_part) "
            + "FROM Po po "
            + "LEFT JOIN po.partList po_part "
            + "LEFT JOIN po_part.part part "
            + "LEFT JOIN po_part.part where po.id = ?1")
    List<ShopOrder> getShopOrder(Long id);

没错,它也在他们的官方网站上提到了: 链接 - https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query - Parveen Verma
否则 po.id = :id - Satish Patro

0

当在本地运行时,请注释掉pom文件中的内容,重新构建Maven项目,然后运行应用程序。

    <!-- <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency> -->

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接