Изучаем Java EE 7 - [88]

Шрифт
Интервал

>em.persist(address);

>tx.commit();


>assertNotNull(customer.getId());

>assertNotNull(address.getId());

В листинге 6.7 customer и address — это всего лишь два объекта, которые располагаются в памяти виртуальной машины Java. Они оба станут сущностями, которые находятся под управлением, когда менеджер сущностей (переменная em) примет их в расчет, обеспечив постоянство (em.persist(customer)). На данном этапе оба объекта окажутся подходящими для вставки в базу данных. Когда произойдет фиксация транзакции (tx.commit()), информация будет сброшена в базу данных, строка, касающаяся адреса, будет вставлена в таблицу ADDRESS, а строка, которая касается клиента, — в таблицу CUSTOMER. Поскольку Customer является владельцем связи, его таблица содержит внешний ключ, ссылающийся на ADDRESS. Выражения assertNotNull обеспечат проверку того, что обе сущности получили сгенерированные идентификаторы (благодаря поставщику постоянства, а также аннотациям @Id и @GeneratedValue).

Обратите внимание на порядок методов persist(): сначала обеспечивается постоянство Customer, а затем — постоянство Address. Если бы этот порядок был иным, то результат все равно оказался бы тем же. Ранее менеджер сущностей был охарактеризован как кэш первого уровня. Пока не произойдет фиксации транзакции, данные остаются в памяти, а доступ к базе данных отсутствует. Менеджер сущностей кэширует данные и, когда готов, сбрасывает их в том порядке, в каком ожидает основная база данных (с соблюдением ограничений целостности). Поскольку внешний ключ располагается в таблице CUSTOMER, сначала будет выполнен оператор insert для ADDRESS, а затем — для CUSTOMER.


Примечание

Большинство сущностей в этой главе не реализуют интерфейс Serializable. Причина этого заключается в том, что сущностям не требуется быть сериализуемыми для того, чтобы оказалось возможным обеспечение их постоянства в базе данных. Они передаются по ссылке от одного метода к другому, и, когда необходимо обеспечить их постоянство, вызывается метод EntityManager.persist(). Но если вам потребуется передать сущности по значению (удаленный вызов, внешний EJB-контейнер и т. д.), то они должны будут реализовывать маркерный (не содержащий методов) интерфейс java.io.Serializable. Этот интерфейс говорит компилятору, что он должен позаботиться о том, чтобы все поля, связанные с классом-сущностью, обязательно были сериализуемыми. Благодаря этому любой экземпляр можно будет сериализовать в байтовый поток и передать с использованием удаленного вызова методов (Remote Method Invocation — RMI).


Поиск по идентификатору

Для поиска сущности по ее идентификатору вы можете использовать два метода. Первый — EntityManager.find(), имеющий два параметра: класс-сущность и уникальный идентификатор (листинг 6.8). Если сущность удастся найти, то она будет возвращена; если сущность не удастся найти, то будет возвращено значение null.


Листинг 6.8. Поиск Customer по идентификатору

>Customer customer = em.find(Customer.class, 1234L)

>if (customer!= null) {

>··// Обработать объект

>}

Второй метод — getReference() (листинг 6.9). Он очень схож с операцией find, поскольку имеет те же параметры, однако извлекает ссылку на сущность (с помощью ее первичного ключа), но не извлекает ее данных. Считайте его прокси для сущности, но не самой сущностью. Он предназначен для ситуаций, в которых требуется экземпляр сущности, находящейся под управлением, но не требуется никаких данных, кроме тех, что потенциально относятся к первичному ключу сущности, к которой осуществляется доступ. При использовании getReference() выборка данных о состоянии является отложенной, а это означает, что, если вы не осуществите доступ к состоянию до того, как сущность окажется отсоединенной, данных уже может не быть там. Если сущность не удастся найти, то будет сгенерировано исключение EntityNotFoundException.


Листинг 6.9. Поиск Customer по ссылке

>try {

>··Customer customer = em.getReference(Customer.class, 1234L)

>··// Обработать объект

>} catch(EntityNotFoundException ex) {

>··// Сущность не найдена

>}


Удаление сущности

Сущность можно удалить методом EntityManager.remove(). Как только сущность окажется удалена, она будет убрана из базы данных, отсоединена от менеджера сущностей и ее больше нельзя будет синхронизировать с базой данных. В плане Java-объектов эта сущность будет по-прежнему доступна, пока не окажется вне области видимости и сборщик мусора не уберет ее. В коде, приведенном в листинге 6.10, показано, как удалить объект после того, как он был создан.


Листинг 6.10. Создание и удаление сущностей Customer и Address

>Customer customer = new Customer("Энтони", "Балла", "[email protected]");

>Address address = new Address("Ризердаун Роуд", "Лондон", "8QE", "Англия");

>customer.setAddress(address);

>tx.begin();

>em.persist(customer);

>em.persist(address);

>tx.commit();


>tx.begin();

>em.remove(customer);

>tx.commit();


>// Данные удаляются из базы данных, но объект по-прежнему доступен

>assertNotNull(customer);

Код из листинга 6.10 создает экземпляр Customer и Address, связывает их (customer.setAddress(address)) и обеспечивает их постоянство. В базе данных строка, касающаяся клиента, связывается со строкой, которая касается адреса, с помощью внешнего ключа; далее в коде удаляется только Customer. В зависимости от того, как сконфигурировано каскадирование (о нем мы поговорим позднее в этой главе), Address может остаться без какой-либо другой сущности, которая ссылается на нее, а строка, касающаяся адреса, станет изолированной.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.