Я думаю, что можно обобщить ответ на ваш вопрос. почти для любой операции JPA требуется транзакция, за исключением поиска/выборки, которые не блокируют объекты (т. е. любая операция JPA, которая не изменяет данные).
(Диспетчер сущностей в области транзакции JTA) В случае диспетчера сущностей в области транзакции JTA лучше цитировать из спецификации (Глава 3 Операции сущностей):
Методы persist, merge, remove и refresh должны вызываться в контексте транзакции, когда используется диспетчер сущностей с контекстом сохраняемости в области транзакции. Если контекст транзакции отсутствует, создается исключение javax.persistence.TransactionRequiredException.
Методы, задающие режим блокировки, отличный от LockModeType.NONE, должны вызываться в контексте транзакции. Если контекст транзакции отсутствует, создается исключение javax.persistence.TransactionRequiredException.
Метод find (при условии, что он вызывается без блокировки или вызывается с LockModeType.NONE) и метод getReference не требуется вызывать в контексте транзакции. Если используется диспетчер сущностей с контекстом сохраняемости в области транзакции, результирующие сущности будут отсоединены; если используется диспетчер сущностей с расширенным контекстом сохраняемости, они будут управляться. См. раздел 3.3 об использовании менеджера сущностей вне транзакции.
(Диспетчер сущностей, управляемый приложением/локальный ресурс) В случае диспетчера сущностей, управляемого приложением, спецификация JPA не дает четкого представления о поведении. В случае Hibernate довольно сложно, что происходит, когда не внутри транзакции (это может зависеть также от драйвера JDBC и режима автоматической фиксации соединения с БД). Прочтите статью Hibernate по этой теме. Настоятельно рекомендуется всегда использовать транзакции для вышеупомянутых операций.
Ко второй части вашего вопроса: если вы вызвали сеттер управляемого объекта и без сброса отсоединили его (т.е. до фиксации транзакции), поведение непонятное/неопределенное, т.е. вам лучше исправить код.
Пример глючного кода:
//begin Transaction
MyEntity entity = em.find(MyEntity.class, 1L);
entity.setField("New value");
em.detach();//it is not sure whether the "New value" will be persisted. To make sure it is persisted, ypu need to call em.flush() before detaching
//commit Transaction
Обычно, если порядок операций БД (не совпадает с порядком операций диспетчера объектов) не важен, вы можете оставить реализацию JPA решать, когда выполнять сброс (например, при фиксации транзакции).
person
Andrei I
schedule
10.02.2014