Re: Hibernate StatelessSession
От: bl-blx Россия http://yegodm.blogspot.com
Дата: 15.04.11 09:17
Оценка: 3 (1)
Здравствуйте, Tomnkz, Вы писали:

T>Добрый день.


T>В описании StatelessSession есть такая фраза:

T>

Due to the lack of a first-level cache, Stateless sessions are vulnerable to data aliasing effects


T>Что-то подобное есть в Java Persistence With Hibernate:

T>

T>You have no guaranteed scope of object identity. The same query produces
T>two different in-memory detached instances. This can lead to data-aliasing
T>effects if you don’t carefully implement the equals() method of your persistent
T>classes.


T>Что имеется ввиду? Как может проявиться этот эффект?

В случае с обычной сессией все объекты, возвращаемые запросами, резолвятся
через кэш по identity. Это строго гарантирует, что для данной сессии одному
и тому же первичному ключу всегда соответствует одна и только одна
ссылка на объект.
В StatelessSession кэша нет. Поэтому первичный ключ отображается в разные
ссылки при разных запросах внутри одной транзакции.
Грубо говоря:

final Serializable id = ...;
final Entity a = statelessSession.load(Entity.class, id);
final Entity b = statelessSession.load(Entity.class, id);
System.out.println(a == b); // печатает false, имеем data-aliasing - две ссылки на одну и ту же сущность
System.out.println(a.equals(b)); // печатает true, если equals имплементирован корректно


В случае же нормальной сессии с кэшем:
final Serializable id = ...;
final Entity a = session.load(Entity.class, id);
final Entity b = session.load(Entity.class, id);
System.out.println(a == b); // печатает true
System.out.println(a.equals(b)); // печатает true, если equals имплементирован корректно


Эмпирический пример, демонстрирующий проблему с data-aliasing:
@Entity
public class A {
   @Id
   Long id;
   boolean active;
}
...
final Serializable id = ...;
final A a = session.load(A.class, id);
// установим флаг для этого объекта
a.active = true;
// а теперь сбросим флаг для всех
final Criteria crit = session.createCriteria(A.class);
for(A item : crit.list()) {
    item.active = false;
}
System.out.println(a.active); // печатает true, хотя мы ожидаем false, так как сбросили флаг для всех
El pueblo unido jamás será vencido.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.