2013-12-03 2 views
1

У меня есть объект Product со списком связанных продуктов (которые также являются объектами продукта). Поле сопутствующих товаров помечается как это:Ограничить количество строк, возвращаемых JOIN FETCH в JPA

public class Product { 

    @JoinTable(name = "RELATED_PRODUCT", joinColumns = { 
     @JoinColumn(name = "PRODUCT_ID", referencedColumnName = "id", nullable = false)}, inverseJoinColumns = { 
     @JoinColumn(name = "RELATED_PRODUCT_ID", referencedColumnName = "id", nullable = false)}) 
    @ManyToMany(fetch = FetchType.LAZY) 
    List<Product> relatedProducts; 
} 

Как вы можете видеть список забирается ленив, что то, что я хочу в большинстве случаев. В некоторых случаях, однако, я хочу, чтобы список связанных продуктов был заполнен немедленно. Я создал запрос для этого с помощью LEFT JOIN FETCH. Тем не менее, я хочу только соответствующие продукты, которые будут добавлены, которые имеют определенный рейтинг, скажем, рейтинг> 3.

Я попытался следующие:

SELECT DISTINCT p FROM Product p LEFT JOIN FETCH p.comparableProducts cp WHERE p.id = :id AND cp.rating > 3 AND CURRENT_DATE BETWEEN p.commenceDate AND p.removeDate 

Но это не работает. Он всегда возвращает обратно все связанные продукты в базе данных, а не только те, которые имеют рейтинг выше 3. Как это можно устранить?

ответ

1

Самый простой способ решить эту проблему - загрузить связанные продукты отдельно, вместо того чтобы пытаться вставить их в поле relatedProducts.

Он также имеет прекрасный смысл с объектно-ориентированной точки зрения. Я полагаю, что у вас есть что-то вроде «страницы продукта», содержащей выбранный продукт и «рекомендуемые продукты». Если да, то такая страница является отдельной концепцией, которая заслуживает своего собственного класса:

public class ProductPage { 
    private Product product; 
    private List<Product> recommendedProducts; 
    ... 
} 

Тогда вы можете заполнить такой класс либо с помощью одного запроса:

SELECT DISTINCT p, cp FROM Product p LEFT JOIN p.comparableProducts cp WHERE p.id = :id AND cp.rating > 3 AND CURRENT_DATE BETWEEN p.commenceDate AND p.removeDate 

или на два отдельных запросов.

К сожалению, этот подход не позволяет получить экземпляр ProductPage непосредственно из JPA, вам необходимо записать код преобразования вручную.

+0

Хм ... немного недостатка, что JPA не может этого сделать или я здесь не прав? Я полагаю, было бы не слишком сложно просто добавить объекты продукта в список с рейтингом> 3. В конце концов, такой механизм можно использовать без выборки (т. Е. Я мог бы получить для «оригинального» продукта, который имеет рейтинг> 3 легко) и также является частью SQL. Я верю вам, когда вы говорите, что ваш ответ - это решение моего вопроса, но это кажется громоздким. Все, что я хочу, это продукт, который содержит связанные продукты. Они являются ЧАСТЬЮ этого перкулярного продукта, поэтому они должны принадлежать ему, даже с объектно-ориентированной точки зрения. – Niles11

+0

Дело в том, что в некотором смысле оно идет в духе JPA, потому что JPA предполагает, что состояние постоянных полей отражает состояние базы данных. – axtavt

+0

Да, я согласен с этим, но моя ситуация выглядит так, как любой программист может быть. Просто типичная проблема отношений. Я действительно думал, что будет хороший и чистый способ сделать это, но, к сожалению, нет. Кажется, мне просто нужно это принять. Спасибо за ответ в любом случае! – Niles11

Смежные вопросы