2012-05-15 1 views
1

Это должна быть простая задача, но я не могу заставить ее работать.Как вернуть изменения в коллекции, принадлежащие сущности в Hibernate?

Я хочу, чтобы иметь возможность возвращать изменения в ленивую коллекцию (назовем ее котятами), свисающие с основной сущностью (назовем ее Cat), которые поддерживаются в одном сеансе Hibernate.

Коллекция определяется как это (замена мои унылые лица с кошками и котятами):

@Entity 
@Table(name="CAT") 
public class Cat { 

    private Map<Long, Kitten> kittens; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="mother", cascade={CascadeType.ALL}) 
    @MapKey(name="id") 
    public Map<Long, Kitten> getKittens() { 
     return kittens; 
    } 

    ... 
} 

@Entity 
@Table(name="KITTEN") 
public class Kitten { 

    private Cat mother; 

    @ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CadcadeType.MERGE) 
    @JoinColumn(name="MOTHER_CAT_ID", nullable=false) 
    public Cat getMother { 
     return mother; 
    } 

    ... 
} 

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

Но если пользователь решит вернуться, исходный список котят следует снова получить из базы данных.

Я пытался достичь этой полной реверсии коллекции по выселению коллекции котят из кэша второго уровня, а затем повторно получать объект Cat из базы данных, используя следующую закономерность:

public class CatDao { 

    public Cat reset(Cat cat) { 

     SessionFactory sessionFactory = Util.getSessionFactory(); 
     sessionFactory.evictCollection(Cat.class.getName() + ".kittens", cat.getId()); 

     Cat original = (Cat)this.session.get(Cat.class, cat.getId()); 
     Hibernate.initialize(original.getKittens()); 

     return original; 
    } 

    ... 
} 

It не восстанавливает котят из базы данных (как показано путем ведения журнала). Что я делаю не так?

ответ

3

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

Кэш первого уровня находится внутри объекта сеанса. Вы должны выселить котят из сеанса, используя Session.evict(). (Session.clear() или создание нового сеанса имеет такой же эффект, но приведет к перезагрузке всех объектов, хранящихся в кеше первого уровня сессии. Это зависит от вашего приложения, если это лучшее решение.)

После этой модификации Я думаю, вам не нужно звонить SessionFactory.evictCollection() в любой момент. Кстати, SessionFactory.evictCollection() отмечен как устаревший.

+0

Спасибо @Johanna. Вы верны по обоим пунктам. – Lisa

Смежные вопросы