Это поведение является одной из основных целей транзакционной деятельности.
Прежде чем транзакционный метод вот-вот вернется, транзакция совершает, то есть все изменения управляемых объектов будут сброшены в базу данных.
Если произошла ошибка, транзакция будет отменена, что означает, что в базу данных не будут внесены изменения.
Возможно, вы пытаетесь получить LazyInitializationException
при попытке доступа к лениво загруженному свойству, вероятно, к коллекции из объекта. Ленообразные свойства не генерируются при получении из базы данных.
Если вы получаете доступ к лениво загруженному свойству в транзакции, поставщик сохранения будет создавать запрос, создать экземпляр результата и прикрепить его к «родительскому» объекту.
РЕДАКТИРОВАТЬ: Если вы хотите, чтобы ленивые свойства были загружены, и иметь возможность изменять вашу сущность без сохранения изменений в БД, вы можете получить сущность с объединениями для получения для ленивых свойств.
em.createQuery("SELECT e FROM MyEntity e JOIN FETCH e.lazyProp");
Далее следует один из способов, описанных в @orid.
Если вы не используете извлечение соединений, вам нужно будет получить доступ к лениво нагруженным свойствам в то же время внутри транзакции:
myEntity.getLazyProp().size();
Обратите внимание на вызов size()
. Вызов получателя недостаточно, так как вы получите прокси. Вам необходимо выполнить операцию, которая требует фактических данных из свойства.
Что происходит, если метод * не * транзакционный? –
Мне действительно нужно @Transactional, чтобы избежать LazyInitializationException – Rachidon