Я думаю, что можно суммировать ответ на ваш вопрос. Для любой операции JPA требуется транзакция, кроме find/selects, которая не блокирует объекты (например, любая операция JPA, которая не изменяет данные).
(JTA транзакции Scoped диспетчер объектов) В случае сделки в области видимости управляющего объектом JTA это лучше процитировать спецификации (Глава 3 Entity Операции):
сохраняется, методы слияния, удаления и обновления должны быть вызваны в пределах контекстом транзакции, когда используется диспетчер сущностей с контекстом персистентности транзакций с областью . Если контекст транзакции отсутствует, генерируется исключение javax.persistence.TransactionRequiredException.
Методы, определяющие режим блокировки, отличный от LockModeType.NONE необходимо вызвать в контексте транзакции. Если контекст транзакции отсутствует, генерируется исключение javax.persistence.TransactionRequiredException.
Метод находки (при условии, что вызывается без замка или вызывается с LockModeType.NONE) и метод getReference не требуется, чтобы быть вызван в пределах контекста транзакции. Если используется менеджер сущностей с контекстом персистентности с транзакцией , результирующие объекты будут отсоединены; если используется менеджер сущностей с расширенным контекстом постоянства , они будут управляться. См. Раздел 3.3 для диспетчера сущностей за пределами транзакции.
(Применение управляемого/ресурсов локального диспетчера объектов) В случае управляющего объекта Application управляемого, спецификация JPA не ясно, о поведении. В случае Hibernate довольно сложно, что происходит, когда не внутри транзакции (это может зависеть также от драйвера JDBC и режима автосохранения соединения БД). Проверьте Hibernate's article на эту тему. В основном вам настоятельно рекомендуется всегда использовать транзакции для вышеупомянутых операций.
Во вторую часть вашего вопроса: если вы вызвали средство управления управляемой сущностью и не очистили, вы отделили его (т.е. до совершения транзакции), поведение нечеткое/неопределенное, то есть лучше исправить код ,
Пример багги кода:
//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
Обычно, если порядок операций БД (не то же самое, как и порядок менеджера enity операций) не имеет значения, вы можете оставить реализацию JPA, чтобы решить, когда (например, при совершении транзакции).
Так что для сеттеров мне нужен флеш, но мне не нужна операция начала/конца? Но зачем смывать? Поскольку я читаю здесь и там, кажется, что flush опустошает кеш sql-команды (немедленно выполнить все операции), но почему бы не позволить JPA-Реализации решить, когда нужно выполнить? – dermoritz
, так что код в порядке, если не вызван em.detach()? не багги код: MyEntity entity = em.find (MyEntity.class, 1L); entity.setField («Новое значение»); – dermoritz
Да, конечно. Это «обычная ситуация». flush будет вызван автоматически при совершении транзакции :) –