Написание статистической функции количества во многих отношениях ко многим в JPA, вызывающих ошибки Hiberate - PullRequest
0 голосов
/ 27 мая 2018

У меня есть две сущности (Порядок и Продукт), которые имеют отношения многие ко многим друг с другом через таблицу ссылок.Мне нужно вернуть все заказы, в которых количество продуктов в заказе> 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;

  @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)
)
  @JsonBackReference
  private List<Product> products = new ArrayList<>();

. . . . Getters and Setters

}

Продукты

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

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

    @JoinTable(name = "order_product", 
        joinColumns = {@JoinColumn(name = "product_id")},
        inverseJoinColumns = {@JoinColumn(name = "order_id")})
    @ManyToMany(fetch = FetchType.EAGER, cascade= CascadeType.ALL)
    @JsonBackReference
    private List<Order> orders;

    . . . Getters and setters . . .

}

Я хочу получить все заказывместе с их продуктами, у которых количество заказов в продукте превышает 2.

Я пробовал несколько вариантов одного и того же запроса.(Проверьте комментарии)

@Repository
public interface OrderRepository extends JpaRepository<Order, Serializable> {

  //@Query("SELECT o from Order o INNER JOIN o.products GROUP BY o.orderId HAVING count(o.products) > 2")
  //@Query("select o from Orders o join o.products p GROUP BY o.orderId HAVING COUNT(p) > 2")
  @Query("SELECT o from Order o join o.products p having count(p) > 2")
  List<Order> findOrderWithMultipleProducts();
}

Если я неправильно смоделировал свои домены, пожалуйста, сообщите мне.

Одна из ошибок, которые я получаю, -

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: having near line 1, column 70 [SELECT o from com.jpa.orders.domain.Order o join o.products p having count(p) > 2]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:288) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    ... 62 common frames omitted

1 Ответ

0 голосов
/ 27 мая 2018

Вы хотите что-то вроде этого:

@Query("SELECT o FROM Order o WHERE size(o.products) > 2")

Что касается выбора продуктов вместе с заказом, я обычно использую для этого @NamedEntityGraph.В вашем случае поместите что-то вроде этого поверх вашей сущности Order:

@NamedEntityGraph(name = "OrderWithProducts",
    attributeNodes = {
            @NamedAttributeNode(value="products")
    }
)

Затем добавьте это в ваш метод репозитория:

@EntityGraph(value = "OrderWithProducts" , type=EntityGraphType.FETCH)

Это объединит сущности и получит ваши данныеиспользуя один запрос.Конечно, вы всегда хотите посмотреть, что SQL Hibernate генерирует для вас, и оптимизировать в соответствии с вашими потребностями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...