【问题标题】:List is not being initialize when using NEW in JPQL在 JPQL 中使用 NEW 时未初始化列表
【发布时间】:2015-06-11 20:23:55
【问题描述】:

我有一个相当简单的查询,它需要几个表的输入。当我尝试运行查询时,它说:

[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

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 = ?1")
    List<ShopOrder> getShopOrder(Long id);

ShopOrder.java

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;

    }

我创建了一个 Juint 测试,通过执行以下操作来查看发生了什么:

@Test
@Transactional
public void shopOrderTest() throws Exception
{

        Po po = new Po();
        Long id = (long) 11;
        LocalDate date = new LocalDate(2015,6,10);
        po.setDue_date(date);
        po.setId(id);
        po.setPo_number("11254");
        po.setSales_order_number("34879");
        po.setStatus("ordered");
        BigDecimal total_sale = new BigDecimal("55");
        po.setTotal_sale(total_sale);

        Part part = new Part();
        BigDecimal brakepress_hrs_per_part = new BigDecimal("34");
        part.setBrakepress_hrs_per_part(brakepress_hrs_per_part);
        BigDecimal grind_hrs_per_part = new BigDecimal("354");
        part.setGrind_hrs_per_part(grind_hrs_per_part);
        part.setId(id);
        part.setInventory_count(55);
        BigDecimal laser_hrs_per_part = new BigDecimal("987");
        part.setLaser_hrs_per_part(laser_hrs_per_part);
        BigDecimal lb_per_part = new BigDecimal("58748");
        part.setLb_per_part(lb_per_part);

        poRes.save(po);
        partRes.save(part);

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

        int size = getOrders.size();

        System.out.println("The size is-----"+size);

        for(ShopOrder order: getOrders){
            System.out.println(order);
        }
    }

}

现在测试通过了,但 List 的大小为 0,这解释了为什么我收到 null 错误。但是我不明白为什么。

给我空错误的方法在这里:

/**
 * Generate Shop Orders.
 */
@SuppressWarnings("null")
@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);
    }

}

Po.java

@OneToMany(mappedBy="po",targetEntity=Po_part.class)
private List<Po_part> partList;


public List<Po_part> getPartList() {
    return partList;
}

Part.java

@OneToMany(mappedBy="part",targetEntity=Po_part.class)
private List<Po_part> partList;

Po_part.java

@ManyToOne
private Part part;

@ManyToOne
private Po po;

我希望这可以解决我的查询问题。如果您对我应该如何进行更好的查询有任何建议,我会全力以赴。

这也是我的数据库表的图片:

【问题讨论】:

  • 在您的方法中,您正在测试shopOrders 是否为空,但是您使用的是shopOrders.toString(),这将导致 NPE。但这不是您的查询失败的原因。您的查询是 LEFT JOINing part 两次。这有什么原因吗?另外,是否有可能不存在任何 JOIN 关系?如果是这样,您可能希望将它们设为 JOIN 而不是 LEFT JOIN。
  • 另外,“THIS WORKED!!!!”的相关性是什么?留言?
  • @DuncanKinnear 我更新了我的帖子。我希望这可以解决问题。
  • @DuncanKinnear 我删除了“它成功了!!!”信息。这只是为了调试目的,我在上传这篇文章之前忘记删除它。
  • 您还没有说明为什么您的查询中有两次LEFT JOIN po_part.part。尝试在 where 之前立即删除第二个。

标签: java jpa jpql


【解决方案1】:
@Query("SELECT NEW com.htd.domain.ShopOrder(pp.po.id, pp.po.po_number, pp.po.due_date, pp.id, pp.part_quantity, "
        + "pp.part.id, pp.part.part_number, pp.part.part_description, pp.part.plasma_hrs_per_part, pp.part.grind_hrs_per_part, "
        + "pp.part.mill_hrs_per_part, pp/part.brakepress_hrs_per_part) "
        + "FROM Po_part pp Where pp.part.id = ?1")
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_part po_part ON po_part.po.id = po.id"
        + "LEFT JOIN Part part ON po_part.part.id = part.id AND po.part.id = ?1")
List<ShopOrder> getShopOrder(Long id);

左连接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多