Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize / 11 сообщений из 11, страница 1 из 1
20.11.2017, 22:56
    #39556437
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
всем привет!

есть сущности

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
package local.hibernate.domain;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@org.hibernate.annotations.NamedQueries({
        @org.hibernate.annotations.NamedQuery(
                name = "class/Item.selectAll",
                query = "select i from item i order by i.id"
        ),
})

@Entity(name = "item")
@Table(name = "item")
public class Item {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    @Column(nullable = false)
    private String name;

    // getter, setter, toString

}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
package local.hibernate.domain;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity(name = "bid")
@Table(name = "bid")
public class Bid {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    @Column(nullable = false)
    private Double price;

    @NotNull
    // defaulf: FetchType.EAGER
    @ManyToOne
    @JoinColumn(name = "item_id", nullable = false)
    private Item item;

    // getter, setter, toString

}



и основная сущность с @Subselect + @Synchronize

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
package local.hibernate.domain;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity(name = "subselect_item")

@org.hibernate.annotations.Immutable

// *** importantly: pure sql query
@org.hibernate.annotations.Subselect(
        " select i.id         as item_id, " +
        "        i.name       as item_name, " +
        "        count(b.id)  as cnt, " +
        "        sum(b.price) as sum " +
        " from   item     as i " +
        "   left join bid as b " +
        "     on b.item_id = i.id " +
        " group by i.id " +
        " order by i.id " )
@org.hibernate.annotations.Synchronize({
        // todo: don't work
        //"item", "bid",
        //"Item", "Bid",
        //"local.hibernate.domain.Item", "local.hibernate.domain.Bid",
})

@org.hibernate.annotations.NamedQueries({
        @org.hibernate.annotations.NamedQuery(
                name = "class/SubselectItem.selectAll",
                query = "select ssi from subselect_item ssi order by ssi.id"
        ),
        @org.hibernate.annotations.NamedQuery(
                name = "class/SubselectItem.selectOne.whereId",
                query = "select ssi from subselect_item ssi where ssi.id = :id"
        ),
})

public class SubselectItem {

    @Id
    @Column(name = "item_id", nullable = false, unique = true)
    private Long id;

    @Column(name = "item_name")
    private String name;

    @NotNull
    @OneToOne
    @JoinColumn(name = "item_id", nullable = false, unique = true)
    private Item item;

    @Column(name = "cnt")
    private Integer count;

    @Column(name = "sum")
    private Double price;

    // getter, setter, toString

}



работа с Item и SubselectItem (у них ключ как видно по запросу одинаковый):
1) достаем в сеансе Item, меняем ему значение поля `name`
2) в этом же сеансе достаем SubselectItem по `Item.id` через em.find()
3) в этом же сеансе достаем SubselectItem по `Item.id` через em.createNamedQuery()

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
// em - EntityManager
worker.start(em -> {
            Item item = getRandomItem(em);
            if (item != null) {
                item.setName("new_value");

                SubselectItem subselectItem = em.find(SubselectItem.class, item.getId());
                SubselectItem subselectItem2 = em.createNamedQuery("select ssi from subselect_item ssi where ssi.id = :id", SubselectItem.class)
                .setParameter("id", id)
                .getSingleResult();
            }
        });



в subselectItem = em.find возвращается значение, в котором `name` содержит старое значение, так и должно быть, т.к. hibernate не выполняет автоматическую синхронизацию перед операцией find()

в subselectItem2 = em.createNamedQuery возвращается значение, в котором `name` тоже содержит старое значение, но так не должно быть , т.к. hibernate должен выполнять автоматическую синхронизацию перед операцией createQuery/createNamedQuery/createNativeQuery.
должен в том случае если таблица Item синхронизирована с SubselectItem

я попробовал все варианты в @Synchronize (написаны выше)
- по имени таблицы (насколько я понял - надо как раз по имени таблицы)
- по имени @Entity
- по полному имени класса
ни один не отрабатывал как положено

есть у кого опыт с @Subselect + @Synchronize, что тут не так?
...
Рейтинг: 0 / 0
21.11.2017, 09:31
    #39556575
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
rmikkiо так не должно быть , т.к. hibernate должен выполнять автоматическую синхронизацию перед операцией
Может синхронизация это перезапрос вместо ленивых свойств? Т.е. всё Ок?
...
Рейтинг: 0 / 0
22.11.2017, 22:30
    #39557914
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
Petro123rmikkiо так не должно быть , т.к. hibernate должен выполнять автоматическую синхронизацию перед операцией
Может синхронизация это перезапрос вместо ленивых свойств? Т.е. всё Ок?

Java Persistence API и HibernateОбратите внимание, что Hibernate не выполняет автоматической синхронизации перед операцией find() - только перед выполнением запроса (Query), если это необходимо.
Hibernate определит, что модифицированный объект Item повлияет на результат запроса, потому что таблица ITEM синхронизирована с ItemBidSummary.
Соответственно, необходимо выполнить синхронизацию изменений и инструкцию UPDATE, чтобы предотвратить возвращение запросом устаревших данных.


ItemBidSummary - в моем случае это сущность SubselectItem

как я понимаю, так как я обновил item.setName("new_value"), то последующий запрос subselectItem2 = em.createQuery уже должен увидеть новые данные и вернуть обноленное имя (name)
...
Рейтинг: 0 / 0
23.11.2017, 00:05
    #39557947
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
Java Persistence API и HibernateСоответственно,
моё imho и прочтение этого:авторСоответственно, необходимо выполнить синхронизацию изменений и инструкцию UPDATE, чтобы предотвратить возвращение запросом устаревших данных.
в том, что надо самому сбросить на диск изменения (UPDATE).
Дай ссылку, где ты это прочитал.
Мне лично бы не понравилось, что ОРМ или JPA сам решает где ему сбрасывать и синхронизировать в базу.
В хибере API это решаю я сам.
авторкак я понимаю, так как я обновил item.setName("new_value"), то последующий запрос subselectItem2 = em.createQuery уже должен увидеть новые данные и вернуть обноленное имя (name)
Ещё про коммит не забыть.
...
Рейтинг: 0 / 0
23.11.2017, 20:14
    #39558599
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
это из книги Бауэр К., Кинг Г., Грегори Г. - JAVA PERSISTENCE API И HIBERNATE

Petro123в том, что надо самому сбросить на диск изменения (UPDATE).

я пробовал и сам сбрасывать

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
worker.start(em -> {
            Item item = getRandomItem(em);
            if (item != null) {
                LOGGER.warn("find: before {}", em.find(SubselectItem.class, item.getId()));
                LOGGER.warn("query: before {}", 
                                em.createQuery("select ssi from SubselectItem ssi where ssi.id = :id", SubselectItem.class)
                                                .setParameter("id", item.getId()).getSingleResult());

                item.setName(item.getName() + "_updated");
                em.flush();
                //em.refresh(item);

                LOGGER.warn("find: after {}", em.find(SubselectItem.class, item.getId()));
                LOGGER.warn("query: after {}", 
                                em.createQuery("select ssi from SubselectItem ssi where ssi.id = :id", SubselectItem.class)
                                                .setParameter("id", item.getId()).getSingleResult());
            }
        });



Petro123Ещё про коммит не забыть

я хочу увидеть данные в той же сессии (сеансе em), а не в новой.
в новой все ок, там данные уже обновленные приходят
...
Рейтинг: 0 / 0
23.11.2017, 20:21
    #39558600
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
Petro123Может синхронизация это перезапрос вместо ленивых свойств? Т.е. всё Ок?

тут нет ленивых свойств, это не относится к полю SubselectItem.item, а только к полю SubselectItem.name
...
Рейтинг: 0 / 0
23.11.2017, 20:21
    #39558601
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
видимо надо глубже в хибер смотреть. видимо мало кто пользуется этим subselect+synchronize
...
Рейтинг: 0 / 0
23.11.2017, 20:22
    #39558602
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
rmikki,
Я смотрю, твоё @Subselect полтора человека использует.
Классику один ко многим не хочешь что ли?
...
Рейтинг: 0 / 0
23.11.2017, 20:24
    #39558603
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
rmikkiвидимо надо глубже в хибер смотреть. видимо мало кто пользуется этим subselect+synchronize
О...пока писал, и ты уже написал.
+1
...
Рейтинг: 0 / 0
23.11.2017, 22:57
    #39558638
rmikki
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
Petro123Я смотрю, твоё @Subselect полтора человека использует.

да я тоже смотрю никто почти не использует, а жаль, вроде как смысл от этого subselect вполне есть - готовый маппинг на свою псевдо-сущность. жаль что synchronize не отрабатывает как надо

Petro123Классику один ко многим не хочешь что ли?

мне это не в проект, а просто для изучения - как и к чему работает. оно же работает, только не на все 100%

на прошлом месте работы познакомился (не сам писал, а видел чужой код) с этим subselect.
тогда уже удивился что synchronize как-то непонятно был расставлен.. наверно он и тогда не влиял особо

спасибо за обсуждение. пусть ру-зоне будет хоть что-то про это :)
...
Рейтинг: 0 / 0
23.11.2017, 23:40
    #39558650
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize
rmikki,
Это замена вьюшки в бд.
Изучать лучше классику.
Именно сущности и отношения.
А не псевдоСущности.
Imho, удачи.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, Subselect + Synchronize. Не отрабатывает Synchronize / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]