Борьба за понимание правильного использования EntityManager

Я начинаю новый проект, и я совершенно не знаком с использованием JPA / Hibernate. Я пытаюсь понять, как правильно использовать EntityManager. Точнее, когда их создавать, сколько мне нужно, я должен закрыть их, должен ли я поместить все в транзакции?

В любом случае, в моем текущем коде, я получил org.hibernate.LazyInitializationException при попытке прочитать объект, который я ранее сохранил. Я бы понял обратное (чтение противовеса в транзакции, а затем попытка сохранить прочитанный объект в другой транзакции, но поскольку транзакция завершена, объект неуправляемый, поэтому сохранение не удается), но этого я не могу понять.

Я поместил свой код в GitHub ( https://github.com/GaetanLeu/intl ), это всего лишь пара classов. Моя основная часть находится в src / sandbox / MessageSandbox.java, и она не работает в строке 28 со следующей командой stacktrace:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) at entity.MessageKey_$$_jvstfcc_0.toString(MessageKey_$$_jvstfcc_0.java) at java.lang.String.valueOf(String.java:2854) at java.lang.StringBuilder.append(StringBuilder.java:128) at com.google.common.base.Present.toString(Present.java:88) at java.lang.String.valueOf(String.java:2854) at java.io.PrintStream.println(PrintStream.java:821) at sandbox.MessageSandbox.main(MessageSandbox.java:28) 

Также я получил предупреждение от Hibernate о том, что мой EntityManager уже существует, что происходит потом? Является ли метод EntityManagerFactory.createEntityManager возrotationм существующего?

 WARN: HHH000436: Entity manager factory name (intl) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name' 

На самом деле я потерял, когда создавать EntityManagers ^^ Любая помощь была бы оценена, но, пожалуйста, простое объяснение. Я действительно новичок в этом.

О, BTW, я хочу точно сказать, что я не использую Spring, у меня нет EJB, я хочу манипулировать EntityManager вручную, пока не пойму. Благодаря 🙂

СущностьManager управляет контекстом персистентности , другими словами, в снимке памяти состояния базы данных.

См. Что такое объект persistence?

Каждый объект, загруженный с помощью entityManager, будет находиться в управляемом состоянии (см. Жизненный цикл сущности), пока вы не закроете EM. Когда объект managed , все изменения, внесенные в него, будут отслеживаться, а затем сохраняться при промывке ЭМ. Если вы получаете доступ к некоторому ленивому атрибуту, запрос будет автоматически инициирован для динамической загрузки данных, но если объект находится в состоянии отсоединения (если EM закрыт), доступ к ленивому атрибуту приведет к ошибке, которую вы получите.

Объем (/ жизненный цикл) вашего EM зависит от вашего контекста выполнения. Например, для веб-приложения для каждого HTTP-запроса обычно создается EM.

Для автономного приложения вам нужно учитывать, может ли firebase database обновляться другим приложением / нитью или нет. Если это возможно, ваш постоянный контекст может не соответствовать состоянию базы данных, и вы должны создать его для каждой единицы работы (транзакции), чтобы этого избежать. В противном случае вы можете создать один экземпляр один раз для всех приложений lifecyle и обновить его регулярно.

Для приложения CRUD жизненный цикл, как правило, следующий:

  • создать EM
  • выбор некоторых объектов (они управляются таким образом, любой доступ к ленивому атрибуту будет загружать данные из БД)
  • закрыть EM (объект теперь отсоединен, любой доступ к ленивому атрибуту приведет к исключению LazyInitializationException)
  • отображение данных пользователю

При проверке обновлений пользователей:

  • создать их
  • открыть транзакцию
  • объедините (присоедините) свои обновленные сущности (это то, что вы вызываете save) (если вы настроили какую-то оптмическую блокировку, em проверит версию сущности на базе данных здесь)
  • в конечном итоге выполнить некоторую проверку бизнеса или дополнительные обновления
  • совершить транзакцию и закрыть em (изменения будут сброшены)

Имейте в виду, что EM – это легкий объект, дешевый для создания и уничтожения, а НЕ РЕЗЬБОЙ.

BTW, JPA – спецификация Java EE, которая является частью EJB (часть сохранения). Его цель заключается в использовании контекста контейнера Java EE (сервер приложений Java EE или CDI с JEE 6). Вы по-прежнему можете использовать hibernate в автономном режиме через контракт JPA, но даже в этом случае необходимо учитывать сцепление с пружиной, чтобы использовать возможности, управляемые контейнером.

  • Пакетные вставки с JPA / EJB3
  • Данные LOAD и CACHE с областью приложения с @Singleton и @Stateless
  • Как создать таблицу объединений с аннотациями JPA?
  • Поддержка JPA для Java 8 новых API даты и времени
  • Hibernate: индивидуальная ленивая загрузка, необязательно = false
  • Дилемма JPA hashCode () / equals ()
  • Весовые данные JPA-запрос с параметрическими свойствами
  • Ошибка проверки: значение недействительно
  • Как использовать @Id со строковым типом в JPA / Hibernate?
  • JPA "@JoinTable" аннотация
  • JPA Query выбирает только определенные столбцы, не используя Query Query?
  • Давайте будем гением компьютера.