Spring Data JPA, спящий режим: обновить все запросы и значения SET, выбрав из другой таблицы

Возможен ли следующий SQL в запросе JPA? Я пытался, но фактические запуски гибернации SQL не кажутся правильными.

Это SQL, который я хочу написать как запрос JPA;

UPDATE movie m SET average_rating = COALESCE((SELECT AVG(stars) FROM rating r WHERE r.movie_id = m.id), 0);

Это запрос JPA;

@Query("UPDATE Movie m SET m.averageRating = COALESCE((SELECT AVG(r.stars) FROM Rating r WHERE r.movie = m), 0)")

И что говорит спящий режим;

Hibernate:
    insert
    into
        HT_Movie
        select
            movie0_.id as id
        from
            Movie movie0_
Hibernate:
    update
        Movie
    set
        average_rating=coalesce((select
            avg(rating1_.stars)
        from
            Rating rating1_
        where
            rating1_.movie_id=id),
        0)
    where
        (
            id
        ) IN (
            select
                id
            from
                HT_Movie
        )

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


person wenic    schedule 05.04.2014    source источник


Ответы (1)


@Query("UPDATE Movie m SET m.averageRating = COALESCE((SELECT AVG(r.stars) FROM Rating r WHERE r.movie = m), 0)")

Это 100% правильно. И спящий режим также работает корректно. Hibernate работает следующим образом:

  1. Создайте временную таблицу HT_Movie и вставьте идентификаторы таблицы Movie.
  2. Создайте запрос JPA целиком, где
  3. Сравните абстрагирование идентификаторов от HT_Movie, чтобы повысить скорость обработки обновлений.

И это не ново, hibernate всегда фабрикует запросы.

person GingerHead    schedule 05.04.2014
comment
ах, ладно, возможно, я что-то где-то пропустил, когда я проверяю столбец medium_rating, он не обновляется. - person wenic; 06.04.2014
comment
Я думаю, что это транзакционная проблема, но методы сохранения из CRUDRepository/JpaRepository в порядке. Мне нужно будет посмотреть поближе. - person wenic; 06.04.2014
comment
Как вы это проверите? - person GingerHead; 06.04.2014
comment
это обновление всего «ГДЕ r.movie = m», если я изменю запрос на его «ГДЕ r.movie = :movie» и передам фильм для обновления, поэтому он выборочно обновляет средний рейтинг одного фильма, это работает. временная таблица идентификаторов, которую он создает, может быть пустой, что объясняет, почему ничего не обновляется. - person wenic; 06.04.2014
comment
решение, которое я получил, будет работать, только если я прочитаю все идентификаторы фильмов, а затем вызову метод репозитория обновления для каждого идентификатора, надеялся получить его, он обновит все в одном запросе - person wenic; 09.04.2014