使用Group By和Having子句编写多对多关系的连接查询

时间:2018-05-24 09:01:53

标签: java hibernate spring-boot spring-data-jpa

我需要退回每个订单中包含2个以上产品的订单。订单和产品有如下多种关系。

@Data
@Entity
@Table(name = "orders")
@JsonInclude(NON_NULL)
public class Order implements Serializable {

    public static final int PRECISION = 2;

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @JsonIgnore
    private String orderId;

    . . .  Other fields . . . .

    @ManyToMany(fetch = EAGER, cascade = ALL)
    @JoinTable(
            name = "order_product",
            joinColumns = @JoinColumn(name = "order_id", updatable = false, nullable = false),
            inverseJoinColumns = @JoinColumn(name = "product_id", updatable = false, nullable = false)
    )
    private List<Product> products = new ArrayList<>();
}

和产品

@Data
@Entity
@Table(name = "products")
public class Product implements Serializable {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @JsonIgnore
    private String productId;

   . . . . Other fields
}

我的SQL查询本来是

SELECT o.order_id, p.product_id from Orders o join 
    OrderProduct op on o.order_id = op.order_id join Product p on   
    op.product_id = p.product_id group by o.order_id, p.product_id having    
    (p.product_id) > 2

我写这个查询的最佳尝试

   @Query("SELECT o from Order o JOIN o.products where o.id = :id GROUP BY o HAVING (o.product) > 2")
  List<Order> findOrderWithMultipleProducts();

返回以下错误。

org.hibernate.QueryException: Not all named parameters have been set: [id] [SELECT o from Order o JOIN o.products where o.id = :id]
    at org.hibernate.internal.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:391) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:373) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:83) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:123) ~[spring-data-jpa-1.11.8.RELEASE.jar:na]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:87) ~[spring-data-jpa-1.11.8.RELEASE.jar:na]

控制器只是直接调用此功能。所需的JSON有效负载就是这样的

{
         "orderId": "order_id",
         "products": [
             {
                 "productId": "product_id_1",
             },
             {
                  "productId": "product_id_2",
             },
             {
                  "productId": "product_id_3",
             }
         ]
     }

1 个答案:

答案 0 :(得分:0)

您的查询的where子句为:id ,其中包含:character。所以hibernate期待一个参数

  @Query("SELECT o from Order o JOIN o.products where o.id = :id GROUP BY o HAVING (o.product) > 2")
  List<Order> findOrderWithMultipleProducts();

如果以某种方式您可以创建查询,然后将参数设置为:

SQLQuery query = SELECT o from Order o JOIN o.products where o.id = :id GROUP BY o HAVING (o.product) > 2
query.setString("id",ValueOfId);

假设ID是String

@Query 注释的其他方法是传递方法中的参数并更改:id以反映参数序列。

@Query("SELECT o from Order o JOIN o.products where o.id = ?1 GROUP BY o HAVING (o.product) > 2")
List<Order> findOrderWithMultipleProducts(int id);

更多细节可以在这里找到: Hibernate Query Annotations