jpql join, где предложение имеет неожиданный эффект - PullRequest
0 голосов
/ 01 января 2012

Используя hibernate, у меня есть следующий запрос

    String PQ = "select k from Customer k inner join k.winterSet vs where vs.year = :year";
    TypedQuery<Customer> tq = legacyEm.createQuery(PQ,Customer.class);
    tq.setParameter("year", DateUtil.getCurrentWinterSeason());
    List<Customer> result = tq.getResultList();

Отображение в Customer составляет

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Winter> winterSet = new HashSet<>(0);

, а зимой

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cnr")
private Customer customer;

Когда я запускаю этот запросЯ получаю только строки от Customer, у которого на самом деле есть связанная строка в Winter с атрибутом year, соответствующим данному параметру.Все идет нормально.Однако для этих объектов Customer их winterSet заполняется всеми связанными объектами Winter, а не только теми, которые имеют желаемое значение в атрибуте year.Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 02 января 2012

Соединение выборки делает трюк:

String PQ = "выберите k из Customer k внутреннее объединение FETCH k.winterSet против vs.year =: year";

Отладка в спящем режиме указывает, чтоПроизведенный sql включает в себя пункт where.Но, поскольку отношение отображается LAZY, коллекция не заполняется из этого запроса, а только объекты Customer.При последующем доступе к коллекции загрузка запускается, но на этом этапе предложение were давно исчезло, и все объекты загружаются.

Однако при использовании "join fetch", который фактически загружает всеОбъекты из запроса сразу, hibernate заполняет все из набора результатов запроса, и, следовательно, в коллекции присутствуют только нужные объекты.Это, конечно, гораздо более эффективно, выполняется только один запрос, и нет необходимости загружать каждый из объектов в коллекции, а просто отбрасывать большинство из них.

Редактировать: работает только в спящем режиме, иможет иметь серьезные побочные эффекты, если результат будет изменен.Смотрите комментарий.

0 голосов
/ 02 января 2012

Это совершенно нормальные и ожидаемые результаты.С помощью отображений вы определяете структуру сущностей, включая отношения с другими сущностями.Запрос определяет, какие из этих объектов находятся в результате.

С помощью FetchType вы можете частично контролировать какой-то постоянный атрибут запрашиваемой сущности, выбранный или нет.Но нет механизма для заполнения только некоторых элементов коллекции.

Если вам нужен результат, представляющий только некоторую часть данных в сущности, вы можете создать новый класс, представляющий частичный результат, и заполнить его запросом и конструктором.выражение.

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