Является ли хорошей идеей часто закрывать и открывать спящие сессии? - PullRequest
3 голосов
/ 15 апреля 2010

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

Является ли хорошей идеей открывать сеанс каждый раз, когда я хочу прочитать объект, а затем закрыть его? Сколько накладных расходов это накладывает на приложение и базу данных (мы также используем пул соединений c3p0)?

Будет ли достаточно просто исключить сущность из сеанса, прежде чем читать его снова?

Ответы [ 3 ]

4 голосов
/ 15 апреля 2010

Вы также можете использовать refresh для перезагрузки объекта. Или evict и clear, как упомянуто @ Божо.

При использовании пула соединений накладные расходы на открытие и закрытие сеанса невелики. Что требует времени, так это построить фабрику сессий.

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

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

MyEntity e = session.load( ... );
...
session.evict(e);         // remove entity from the cache
String p = e.myProperty;  // still the value at the time it was loaded
e = sesssion.load( ... ); // latest value

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

MyEntity e = session.load( ... );
...
session.refresh( e );     // refresh entity and cache
String p = e.myProperty;  // latest value
e = sesssion.load( ... ); // latest value

Код выше - только псевдокод, я его не проверял.

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

1 голос
/ 15 апреля 2010

Да. evict() объект. Если вы хотите очистить весь сеанс, clear() it.

Новый сеанс должен быть связан либо с запросом (потоком), либо с более продолжительным диалогом.

0 голосов
/ 15 апреля 2010

Для столбцов, которые ссылаются на другие таблицы, если вы установите для fetch type значение LAZY, Hibernate не будет загружать эти данные до тех пор, пока их явно не попросят. Это экономит много времени.

Столбец в Table может быть помечен:

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="other_table_id", nullable = false)
private OtherTable otherTable;

Таким образом, до тех пор, пока вы не сделаете что-то вроде Table.getOtherTable().getValue(), OtherTable не будет загружен в сеанс. Поэтому, если вы не делаете что-то такое, вам также не нужно выселять это.

Обратите внимание, что это псевдокодиш и может немного отличаться для вашей программы.

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