2013-11-23 3 views
1

Я рассматриваю возможность использования JPA в приложении, чтобы сохранить количество объектов.Ручное управление обновлением базы данных с помощью JPA

Использование приложения, похоже, не согласуется со стандартным подходом JPA для обновления при каждом изменении объекта.

Использование приложения будет таким, что одновременно будет активным только несколько сотен объектов, но каждый из них будет обновляться несколько раз в секунду.

Хотя приложение имеет объекты в памяти, им не нужно постоянно обновляться в базе данных, это просто бесполезно.

Возможно ли использовать JPA для загрузки нескольких объектов в сеанс и, не затрагивая другие объекты, управляемые объектами, внести изменения в них в памяти в течение нескольких минут, а затем обновить базу данных?

Было бы очень полезно, если бы был способ сделать это, если некоторые из объектов были разделены между сеансами.

ответ

1

Если вы хотите, чтобы никакие изменения БД не были внесены в ваши объекты, вы просто отсоединяете их от своего Менеджера сущностей.

  1. Чтобы отделить объект от менеджера объекта во время транзакции, просто используйте метод detach.
  2. Если объект не управляется (то есть после завершения транзакции), что объект все равно не управляется, и вы можете изменить его без дополнительного кода.

выдержка из спецификации JPA 2.0, от того, как субъект получает отдельно:

удаленных результатов сущности из транзакции, если используются транзакций Scoped управляемого контейнер диспетчер объектов (см раздел 3.3); от откат транзакции (см. раздел 3.3.2); от удаление объекта из контекста сохранения; от очистки контекста постоянства ; от закрытия администратора объекта; или сериализация объекта или иным образом передавая объект по стоимости, например, в отдельное приложенными ния уровень, через удаленный интерфейс и т.д.

А потом, когда решите внести изменения БД, вам просто объединить отдельный объект: entityManager.merge(entity);.

Что я думаю о том, что вы пропустили какой-то фон JPA, например, какие состояния сущности и какие операции с объектом entityManager. Я рекомендую либо искать некоторые учебники, либо читать некоторые главы из JPA spec (читайте главу 3.2 Жизненный цикл экземпляра объекта , около 5 страниц, и я гарантирую, что вы поймете много). Кроме того, если вы хотите, чтобы ваши операции MERGE были каскадом, есть также решение для этого в JPA. Для операций на EntityManager & хорошее введение в JPA: the official tutorial.

ОБНОВЛЕНИЕ Я попытаюсь описать вас в ближайшее время, что в этих учебниках важно найти.

Экземпляр сущности (т.е.e постоянный объект java) управляется, если он связан с контекстом постоянства (~ EntityManager). Если он управляется, то его изменения отслеживаются, что означает, что изменение экземпляра управляемого объекта будет синхронизироваться с БД. Изменения синхронизируются с БД, например. когда транзакция завершена или когда вы вызываете entityManager.flush() (подробнее см. подраздел 3.2.4 «Синхронизация с базой данных»).

операция слияния - фактически операция, с которой вы оба обновляете и сохраняете экземпляр объекта E1. Он возвращает экземпляр управляемой сущности E2, в то время как переданный объект E1 остается не управляемым.

отдельностоящий объект на другой стороне не отслеживаются entityManager, то есть EntityManager не будет видеть изменения, которые вы делаете, пока вы не сливаются объект.

Обе операции (есть также операция сохранения, которую я не обсуждал) - это ваш способ переключить состояние экземпляра объекта, управляемого < -> отсоединенным.

Актуально о вашем запросе о root & children: Если ничего не настроено, вызов merge() или detach() на ваш корень не повлияет на ваших детей. Но есть каскадная схема, которую вы можете использовать в JPA, так что, например, вызывающий entityManager.merge(root), будет также вызван на его дочерних элементах. Конечно, вам решать, какой каскад операции, а какой нет.

+0

Я хочу сделать изменения в БД, я просто хочу контролировать, когда это произойдет, и к каким объектам. –

+1

Обновлен мой ответ. Вам просто нужно переместить объекты между отключенным и управляемым состоянием. –

+0

Спасибо! Один последний маленький вопрос: Какова область слияния и отсоединения? Скажем, у меня есть ряд «корневых объектов» с отношением OneToOne или OneToMany к некоторым другим объектам, которые могут быть разделены между корневыми объектами. Что происходит, когда я вызываю отсоединение и слияние на корневых объектах? Я вызываю методы только для корневых объектов или для всех дочерних объектов? –

1

Вы можете контролировать продолжительность жизни объектов посредством создания собственного менеджера сущностей.

Непонятно, если вы говорите о JEE или отдельном приложении, но в любом случае вам нужно получить доступ к фабрике менеджеров сущностей и получить от него диспетчер сущностей.

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

Если вы используете локальные транзакции ресурсов, вы можете контролировать, когда ваши изменения будут сброшены в базу данных. Таким образом, вы можете вносить изменения в свой контекст на определенное количество времени, а затем решили сбросить его, совершив транзакцию или вызвав метод flush.

Возможно, вы захотите прочитать this another answer, чтобы лучше понять контексты персистентности и как они работают.

--Edit--

Есть несколько способов, чтобы получить доступ к вашему менеджеру предприятия заводу в зависимости от типа приложения, которое вы строите.

Если это отдельное приложение, вы можете сделать

EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit-name"); 

Если вы используете рамки инъекции зависимостей, то вы можете использовать его, чтобы ввести его автоматически. Если вы находитесь в приложении JEE, вы можете получить его автоматически для ввода, используя

@PersistenceUnit(unitName="main") 
private EntityManagerFactory emf; 
+0

Когда вы говорите о создании, вы имеете в виду реализацию или создание экземпляра? Что я имею в виду, мне нужно создать свой собственный класс entitymanager, или этого будет достаточно, чтобы просто завладеть фабрикой entitymanager и создать собственный экземпляр? –

+1

@MartinNielsen Я отредактировал свой ответ, чтобы дать вам более подробную информацию. –

+0

И у меня 1up'ed соответственно, спасибо :) –

Смежные вопросы