Hibernate JOIN FETCH - объекты появляются несколько раз в Resultset - PullRequest
0 голосов
/ 25 сентября 2018

Я использую Spring JPA и Hibernate для создания REST API.Я ищу в течение 2 дней, но я не нашел решения, чтобы решить эту проблему.

В некоторых запросах у меня есть несколько предложений JOIN FETCH.Когда я выполняю свой запрос, у меня в родительском наборе несколько раз появляется родительский объект, фактически точно так же часто, как у отца есть дети.
Пример:

    @Query("SELECT DISTINCT p AS post," +
        " <some subquery>" +
        "FROM Post p  JOIN FETCH p.user u LEFT JOIN FETCH p.linkedUsers INNER JOIN FETCH p.track track  " 
        "WHERE ( (<some condition>) OR p.user = :me) " +
        "ORDER BY p.created DESC")
List<Object []> getData(@Param("me")User me,
                                 Pageable pageable);

Например, если у меня есть сообщение с2 связанных пользователя, мой пост появится как минимум 2 раза в моем наборе результатов.Если я не выполняю JOIN FETCH или другое JOIN, данные загружаются лениво.Но это не цель для меня, так как это приводит к плохой работе.

Редактировать: Мой вопрос в том, как выполнить один запрос, при котором все данные извлекаются и все сообщения, удовлетворяющие заданным критериям, имеют ОДИН раз в моем наборе результатов.

Редактировать:

Пример объекта:

 [{
    "id": 1767,
    "track": {
        "id": 1766,
        "title": "VVS",
        ...
        "streams": [
            {
                "id": 1764,
                 ....
            },
            {
                "id": 1765,
                  ...

            }
        ],
        "isrc": "DEQ021801393"
    },
    "user": {
        "id": 999998,
        "username": "My username",
         ....

    },
    "created": "2018-08-21T22:18:56.451Z",
     ...
    "linked_users": []
},
<this object another time, beacause two stream objects in track>
<many other objects two times>
...
]

Редактировать:

Оказалось, что подзапросы находятся в конфликте с "отличным",Если я удаляю их из запроса, я получаю различные сообщения.Если я отредактирую собственный SQL-запрос и изменим «отличный» на «отличный от», он будет работать.Но я думаю, что в режиме гибернации не существует отдельного предложения.Так какие-нибудь хорошие идеи, что делать?

Буду признателен за любую помощь:)

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Если кому-то интересно, как я решил проблему:

После нескольких недель игнорирования этой проблемы я нашел решение.Я вполне уверен, что это не может быть решено с помощью HQL, поэтому я написал собственный запрос с помощью метода json_build_object postgreSQLs.Все данные создаются на уровне базы данных и извлекаются в виде списка объектов JSON.Преимущество этого в том, что производительность запроса намного выше.

Структура запроса:

SELECT DISTINCT ON(post.created)json(json_build_object('id',...
'user', (SELECT json_build_object('id',... 
            FROM users WHERE users.id = post.user_id)
'track', (SELECT json_build_object('id',....
     'streams',ARRAY(SELECT json_build_object('id'...
FROM
<APPORXIMATELY Same JOINS AS BEFORE>
WHERE
<CONDITIONS>

Выполнение запроса из SpringBoot:

 List<JsonNode> decoratedPosts = (List<JsonNode>) entityManager
                .createNativeQuery(NativeQueries.getPostsByUser)
                .setParameter("userId", user.getId())
                .setParameter("me", requestor.getId())
                .setParameter("limit", pageable.getPageSize())
                .setParameter("offset", pageable.getOffset())
                .unwrap(org.hibernate.query.NativeQuery.class)
                .addScalar("json", JsonNodeBinaryType.INSTANCE).getResultList();

Чтобы получить эту работу, необходима следующая зависимость (в зависимости от версии в спящем режиме):

    <dependency>
        <groupId>com.vladmihalcea</groupId>
        <artifactId>hibernate-types-52</artifactId>
        <version>2.3.4</version>
    </dependency>

И спящий диалект нужно расширять.

public class MariosPostgreSQL94Dialect extends PostgreSQL94Dialect {

public MariosPostgreSQL94Dialect() {
    super();
    this.registerColumnType(Types.OTHER, "json");
}
0 голосов
/ 25 сентября 2018

В jpa 2.1 он поддерживает граф сущностей для решения «Дубликатов и проблем N + 1»

@NamedEntityGraph(name = "graph.Order.items", 
               attributeNodes = @NamedAttributeNode(value = "items", subgraph = "items"), 
subgraphs = @NamedSubgraph(name = "items", attributeNodes = @NamedAttributeNode("product")))

Использование графа сущностей для загрузки данных:

Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);

return this.em.find(Order.class, orderId, hints);

Подробнее:

https://www.thoughts -on-java.org / jpa-21-entity-graph-part-1-named-entity /

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