Bezdepbonusu7Программирование: статьи и ответы

Вопрос

JPA EntityManager: сохранять объекты только при явном запросе

Автор вопроса: xlecoustillierОтветов: 1

Я новичок в Hibernate и JPA и в настоящее время работаю над приложением, которое использует его через EntityManager JPA.

Глядя на некоторые базовые руководства по спящему режиму с использованием сеанса гибернации, я вижу, что могу сделать:

val session = HibernateUtil.getSessionFactory().getCurrentSession()
session.beginTransaction()
val coordinates = session.find(Coordinates::class.java, "12345")
coordinates.longitude = 0.0
session.save(coordinates)
session.getTransaction().commit()

При использовании Entitymanager это делается так:

val em = emFactory.createEntityManager()
em.transaction.begin()
val coordinates = em.find(Coordinates::class.java, "12345")
coordinates.longitude = 0.0
em.transaction.commit()

Основное отличие здесь в том, что при использовании EntityManager мне не нужно явно вызывать функцию save для фактического обновления объекта, который в конечном итоге будет сброшен во время фиксации. Конечно, я мог бы сделать что-то вроде

if(obj.id == null) {
    return em.merge()
} else {
    val saved = em.persist(obj)
    return saved
}

Но какой смысл в уже существующих объектах, если они все равно сохраняются, независимо от того, вызываю я это или нет?

Удивительно, но примеры можно найти здесь похоже, также полагаются на метод сохранения.

Мой вопрос: есть ли способ настроить EntityManager для обновления объектов только по запросу (т.е. имитировать поведение сеанса)? Или мне нужно использовать Session для достижения этого?

  • Идея менеджера сущностей заключается в том, что он, как следует из его имени, управляет сущностями (которые привязаны к транзакции, в которой живет менеджер сущностей). Возможно, вам нужно объяснить вашу реальную проблему, чтобы мы могли понять, чего вы хотите достичь, вместо того, чтобы спрашивать о технических особенностях JPA. merge на EM можно использовать, например, для e. грамм. повторно присоединять объекты к сеансу без необходимости перезагрузки объекта и заполнения полей на основе отсоединенного объекта. Smutje 29.05.2020
  • Я понимаю это, конечно. Моя проблема именно та, которую я описал: меня просят сохранять объекты только по запросу (т.е. вызов метода сохранения, что означает, что измененный объект должен быть отброшен, если он не сохранен явно). Я пытаюсь оценить, смогу ли я быстро исправить ситуацию, используя существующий EntityManager, или мне придется переключиться на использование сеанса, что будет стоить немного больше. xlecoustillier 29.05.2020
  • Зачем вы меняете сущности, если не хотите, чтобы они менялись? ;-) Простой способ выйти из запроса, отбрасывая все изменения в JEE, - это выдать @ApplicationException(rollback=true), который, как предполагает его параметр, вызывает откат транзакции. Smutje 29.05.2020
  • Но, тем не менее, моя точка зрения остается в силе: вы не упомянули, почему вы хотите отменить изменение объекта, а только то, что вам нужна такая возможность. Smutje 29.05.2020
  • На самом деле причин несколько: бывают случаи, когда сущности модифицируются, но затем появляются бизнес-правила, требующие отмены этих изменений (вы можете сомневаться в правильности структуры кода, но пока она написана именно так). Еще один момент заключается в том, что этот код исходит из приложения, которое изначально не использовало СУБД (но использовало хранилище данных nosql), которое вообще не имело представления о контексте сохраняемости. Все это было абстрагировано за обычными вызовами CRUD, поэтому меня попросили по возможности сохранить то же поведение. Но я думаю, это ответ на. xlecoustillier 29.05.2020

javakotlinhibernatejpaentitymanager

Ответы

Ответ 1 · рейтинг 1 · Will Hartung

merge - это возможность для EntityManager фактически выполнять операции с базой данных. Слияние, сохранение, сброс и фиксация - это, по сути, все точки контакта с базой данных.

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

Они не совершены, но они произошли. Ключи назначены для родителей и детей, сработали триггеры, сработали методы жизненного цикла, все "как должно быть", "прямо сейчас" и "когда-нибудь в будущем", даже если это может быть всего в миллисекундах.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы