2016-11-04 92 views
0

我需要列出所有Product记录是否有相应的ForeignProductInfoProductForeignProductInfo没有提及。休眠加入生成无效查询

我使用这个JPA查询:

@Query("select distinct fpi from Product pp " 
     + "left join fetch ForeignProductInfo fpi on fpi.partner.id = :partnerId " 
     + "left join fetch fpi.product p ") 
public List<ForeignProductInfo> loadAllForPartner(@Param("partnerId") Long partnerId); 

这工作,直到我添加第二个连接(以避免N + 1次查询的访问ForeignProductInfo.product时)。然后,它生成此SQL:

SELECT 
    foreignpro1_.id AS id1_7_0_, 
    product2_.id AS id1_12_1_, 
    productsub3_.id AS id1_18_2_, 
    productgro4_.id AS id1_14_3_, 
    foreignpro1_.code AS code2_7_0_, 
    foreignpro1_.name AS name3_7_0_, 
    foreignpro1_.partner_id AS partner_4_7_0_, 
    foreignpro1_.product_id AS product_5_7_0_, 
    product2_.a AS a2_12_1_, 
    product2_.b AS b3_12_1_, 
    product2_.comment AS comment4_12_1_, 
    product2_.conversionMethod AS conversi5_12_1_, 
    product2_.diaMax AS diaMax6_12_1_, 
    product2_.diaMin AS diaMin7_12_1_, 
    product2_.len AS len8_12_1_, 
    product2_.mu AS mu9_12_1_, 
    product2_.name AS name10_12_1_, 
    product2_.nameLang1 AS nameLan11_12_1_, 
    product2_.nameLang2 AS nameLan12_12_1_, 
    product2_.productSubGroup_id AS product15_12_1_, 
    product2_.surfaceMax AS surface13_12_1_, 
    product2_.surfaceMin AS surface14_12_1_, 
    productsub3_.name AS name2_18_2_, 
    productsub3_.productGroup_id AS productG3_18_2_, 
    productgro4_.name AS name2_14_3_, 
    productgro4_.seq AS seq3_14_3_ 
FROM 
    Product product0_ 
     LEFT OUTER JOIN 
    ForeignProductInfo foreignpro1_ ON (foreignpro1_.partner_id = 3); 

正如你所看到的,第二个连接丢失,并导致异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'product2_.id' in 'field list' 

编辑:ForeignProductInfo具有零或每个Product的组合中的一个记录, Partner

@Entity 
public class ForeignProductInfo { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long id; 

    @ManyToOne 
    private Partner partner; 

    @ManyToOne 
    private Product product; 

    @Column(length=50) 
    @Size(max=50) 
    private String code; 

    @Column(length=200) 
    @Size(max=200) 
    private String name; 
    ... 
} 
+0

如果我得到这个权利,在你的模式中'ForeignProductInfo.product'指向原来的'Product',对吧? – coladict

+0

如果是这样,看起来你的显式声明'on fpi.partner.id =:partnerId'会覆盖任何可能生成的'on'条件,我们可以看到,它只会生成一个查询条件,我猜你不需要第二次连接,只需要使用如果您需要更详细的话,请在fpi.partner.id =:partnerId和fpi.product = pp'上,或者在fpi.partner.id =上:partnerId和fpi.product.id = pp.id'。 – coladict

+0

是,它指向最初的'Product',它也有一些需要获取的关系。不幸的是,你的建议解决方案在查询验证过程中失败:'由于:java.lang.IllegalArgumentException:org.hibernate.QueryException:查询指定加入提取,但th的所有者e提取的关联没有出现在选择列表中 – Arthur

回答

0

我在3天内无法弄清楚。这是SQL中最简单的事情,但在JPA中似乎无法实现。还尝试了标准API,但条件获取不可能,只有条件连接。

我最后走了一个Product的列表并加载他们的ForeignProductInfo一个接一个。 :(然后抛弃JPA,并使用普通的SQL来做这件事。