Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate проблемы с кешем 
:(
    Опции темы
pnd_ku
Дата 30.3.2009, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Всем добрый вечер!
Суть проблемы следующая:
есть 2 POJO объекта и с соотношением один-ко-многим..

процесс такой: 
1)извлекается набор родителей
2)потом к одному из родителей добавляется детёныш (smile)
3)заново извлекаеца набор родителей.. в этом наборе, при запросе детёнышей у конкретного родителя к которому добавляли, новый не появляется

мои подозрения падают на кеш и на флаш сессии.. но флаш отрабатывает нармально, то есть после добавления детёныша в набор он сразу же отображаеца в базе

собственно маппинги:

родитель

Код

<hibernate-mapping>
  <class catalog="doctor" name="VOs.AvailableSlot" table="AvailableSlots">
    <id name="id" type="java.lang.Integer">
      <column name="ID"/>
      <generator class="identity"/>
    </id>
    <many-to-one class="VOs.Therapiest" column="therapiestId" lazy="no-proxy" name="therapiest" not-null="true"/>
    <property name="dateTime" type="timestamp">
      <column length="19" name="dateTime" not-null="true"/>
    </property>
    <property name="availableSlots" type="byte">
      <column name="availableSlots" not-null="true"/>
    </property>
    <property name="comment" type="string">
      <column length="65535" name="comment" not-null="true"/>
    </property>
    <property name="colorFg" type="string">
      <column length="6" name="colorFG" not-null="true"/>
    </property>
    <property name="colorBg" type="string">
      <column length="6" name="colorBG" not-null="true"/>
    </property>
    <set lazy="true" name="bookings">
      <key column="slotID"/>
      <one-to-many class="VOs.Booking"/>
    </set>
  </class>
</hibernate-mapping>



детёныш

Код

<hibernate-mapping>
  <class catalog="doctor" name="VOs.Booking" table="Bookings">
    <id name="id" type="java.lang.Integer">
      <column name="ID"/>
      <generator class="identity"/>
    </id>
    <many-to-one class="VOs.AvailableSlot" column="slotId" lazy="no-proxy" name="availableSlot" not-null="true"/>
    <many-to-one class="VOs.Patient" column="patientID" lazy="no-proxy" name="patient" not-null="true"/>
    <property name="status" type="byte">
      <column name="status" not-null="true"/>
    </property>
    <property name="payedValue" type="float">
      <column name="payedValue" not-null="true" precision="12" scale="0"/>
    </property>
    <property name="comment" type="string">
      <column length="65535" name="comment" not-null="true"/>
    </property>
  </class>
</hibernate-mapping>



куда хоть копнуть? спасиба!  smile 

PM MAIL   Вверх
pnd_ku
Дата 30.3.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Уфф.. обнаружил проблему..
теперь интересно услышать объяснение от опытных - как так получилось

вот тест кейз:

Код

//показать информацию о слотах и заказах
        List slots = MainDAO.getAvailableSlotsDAO().getAll();
        for(Object o: slots) {
            AvailableSlot slot = (AvailableSlot) o;
            System.out.println("==== " + slot.getId());
            Set bookings = slot.getBookings();
            System.out.println("- " + bookings.size());
            System.out.println();
        }

//создать новый заказ для слота
        AvailableSlot currentSlot = MainDAO.getAvailableSlotsDAO().get(15);

        Booking booking = new Booking();
        booking.setAvailableSlot(currentSlot);
        booking.setPatient(MainDAO.getPatientsDAO().get(1));
        booking.setPayedValue(0);
        booking.setStatus(new Byte("0"));
        booking.setComment("");

        MainDAO.getBookingsDAO().save(booking);

        currentSlot.getBookings().add(booking);
        MainDAO.getAvailableSlotsDAO().save(currentSlot);
        

        System.out.println("------------------------------------- ");

//показать опять
        slots = MainDAO.getAvailableSlotsDAO().getAll();
        for(Object o: slots) {
            AvailableSlot slot = (AvailableSlot) o;
            System.out.println("==== " + slot.getId());
            Set bookings = slot.getBookings();
            System.out.println("- " + bookings.size());
            System.out.println();
        }


Всё решилось добавлением вот этих двух строк

currentSlot.getBookings().add(booking);
MainDAO.getAvailableSlotsDAO().save(currentSlot);

Нет, ну понятно что новый заказ для слоиа нужно сохранить. Но зачем его ручками добавлять в коллекцию этому слоту?
Слоты извлекаюца второй раз заново, как указать Hibernat`у  что нужно заново извлечь и заказы?
PM MAIL   Вверх
MisterCleric
Дата 31.3.2009, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



Здравствуй. Я скажу такое:
это издержки Object Relation Mapping. Это в базе все просто: сказали в Bookings форинг кей на AvailableSlots и механизмами реляционности новые записи становятся известны. JAVA - это же не данные, а только объекты. Так что если надо что бы один объект знал о другом, то ему насильно надо об этом сообщить.
От сюда делаем разбор твоего размышления
Цитата

1)извлекается набор родителей
2)потом к одному из родителей добавляется детёныш (smile)
3)заново извлекаеца набор родителей.. в этом наборе, при запросе детёнышей у конкретного родителя к которому добавляли, новый не появляется


Вроде как бы все правильно. Но тут я уверен, что все эти операции производились в рамках одной Session. Т.е. первый раз набор родителей извлекался все-таки из базы. Операция инсерта тоже пошла в базу. Ну а вот последняя операция не пошла в базу. Так как сработал "кеш первого уровня"

Цитата

 <set lazy="true" name="bookings">
      <key column="slotID"/>
      <one-to-many class="VOs.Booking"/>
    </set>


Нужно lazy="false", если вдруг ты закроешь Session, а потом тебе понадобится коллекция bookings. Т.е. доставать коллекцию "детеныешей" насильно.
Цитата

currentSlot.getBookings().add(booking);
MainDAO.getAvailableSlotsDAO().save(currentSlot);


можно было и без добавления в коллекцию. Можно вызвать на currentSlot refresh - тогда в базу пойдет насильный запрос.

Можно и без refresh и без добавления в коллекцию. но тогда операции инсерта и дальнейшего обновления currentSlot надо делать в разных Session.
Вроде все.


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
pnd_ku
Дата 31.3.2009, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 25.9.2006

Репутация: нет
Всего: 1



Цитата

Т.е. первый раз набор родителей извлекался все-таки из базы. Операция инсерта тоже пошла в базу. Ну а вот последняя операция не пошла в базу. Так как сработал "кеш первого уровня"


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

Цитата

Нужно lazy="false", если вдруг ты закроешь Session, а потом тебе понадобится коллекция bookings. Т.е. доставать коллекцию "детеныешей" насильно.


Это правда, но бывают ситуации когда мне нужна коллекция кучи слотов, но без букингов. А если поставить фолс, то ещё и тянеца огромная куча букингов автоматически. Но это уже да - специфика приложения.

Цитата

можно было и без добавления в коллекцию. Можно вызвать на currentSlot refresh - тогда в базу пойдет насильный запрос.


Вот это классно! спасиба, не подозревал smile Подозревал что какойто апдейт должен быть, но пошел иным путём.

Вообще огромадное спасиба за такой развёрнутый ответ! Мне очень помогло, и надеюсь ещё камунить поможет  smile 

Это сообщение отредактировал(а) pnd_ku - 31.3.2009, 21:26
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0450 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.