Статьи

Эффективное сочетание Flex и Hibernate: основы

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

Если вы программист на Java и работаете с приложениями, ориентированными на данные, вы, вероятно, хорошо знакомы с базами данных, особенно с реляционными базами данных. Большинство современных приложений хранят постоянные данные в популярных механизмах хранения данных, таких как базы данных, большинство из которых имеют реляционный характер. Реляционные базы данных, возможно, не будут самым популярным вариантом в будущем. Появление NoSQL и хранилищ данных в стиле BigTable бросает вызов его повсеместному превосходству.

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

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

Хотя я бы не стал много объяснять о несоответствии между объектами, я, безусловно, могу сказать, что наиболее широко принятым решением проблемы является инструмент, относящийся к категории объектно-реляционного сопоставления (ORM). Такие инструменты уменьшают импеданс потока и обмена данными между объектом и табличными форматами. Однако инструменты ORM — не единственные формы мостов между объектным и реляционным миром. Альтернативы , как использование 1 «активная запись» модели также является жизнеспособным вариантом. Hibernate — это популярное ORM-решение с открытым исходным кодом на основе Java.

Hibernate формирует основу для API Java Persistence, который является стандартной архитектурой персистентности для корпоративных приложений Java.  Положение Hibernate в типичном стеке Java EE понятно, но его место в приложении с интерфейсом Flex и серверной стороной Java не всегда так ясно. Мнения о его удобстве использования варьируются от того, является ли он критическим постоянным слоем до постороннего слоя дезинтермедиации. Хотя я явно не придерживаюсь какой-либо позиции, я надеюсь, что после прочтения этой статьи вы сможете решить для себя плюсы и минусы ее включения.

Приложения Flex программируются на ActionScript 3 (AS3) и MXML, декларативном языке, который переводится на AS3. AS3, как и Java, является объектно-ориентированным языком. Следовательно, несоответствие объектного / реляционного импеданса становится актуальным и в приложениях Flex, хотя приложения Flex практически никогда не обращаются к базам данных напрямую. Приложения Flex подключаются к хранилищам данных через средний уровень Java, где большая часть мостов между двумя мирами объектов и реляционными данными является ответственностью уровня Java. Поэтому приложения Flex со средним уровнем Java или сервисным уровнем могут использовать Hibernate в качестве решения ORM. Когда объекты домена Flex близко моделируют объекты модели Java, отображения остаются релевантными от ORM до уровня пользовательского интерфейса. Сочетание Flex и Hibernate дает большие преимущества с точки зрения повторного использования,масштабируемость и эффективное постоянство. Эффективное объединение не всегда тривиально, у него есть свои проблемы. В этой статье вы узнаете о некоторых из этих проблем и их возможных решениях.

С учетом сказанного давайте рассмотрим несколько вещей об объектно-реляционном несоответствии, самой причине существования Hibernate.

Несоответствие реляционных объектов

Чтобы понять, где и как возникают несоответствия, давайте рассмотрим несколько примеров. Допустим, вы решили создать приложение для каталогизации всех опубликованных компьютерных книг. Затем вам понадобится информация об опубликованных книгах, авторах, написавших эти книги, и компаниях, опубликовавших эти книги. Кроме того, вам необходимо установить соответствующие отношения между этими тремя объектами: книгами, авторами и издателями.

Первое несоответствие, которое возникает, касается гранулярности определений сущностей.

Крупнозернистый и мелкозернистый

В частности, давайте рассмотрим издателя. У издателя, скорее всего, есть имя и контактная информация, которая может включать физический адрес, номер телефона, номер факса и адрес электронной почты. Используя объектно-ориентированные принципы, можно смоделировать издателя следующим образом:

public class Publisher
{
private int publisherId;
private String name;
private ContactInfo contactInfo;

//accessor methods
}

public class ContactInfo
{
private Address address;
private String phone;
private String fax;
private String email;

//accessor methods
}

public class Address
{
private String street;
private String unit;
private String city;
private String state;
private int zip;

//accessor methods

}

 

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

create table publishers (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(100),
street VARCHAR(75),
unit VARCHAR(75),
city VARCHAR(75),
state VARCHAR(75),
zip INT,
phone VARCHAR(75),
fax VARCHAR(75),
email VARCHAR(75)
);

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

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

Помимо детализации, другие большие проблемы связаны с отсутствием объектно-ориентированных концепций наследования и полиморфизма в реляционном мире.

Наследование и полиморфизм

Рассмотрим автора на этот раз. Допустим, имя автора может быть его настоящим именем или псевдонимом или псевдонимом. В мире объектов можно представить это как тип AuthorName и иметь RealName и PenName как два конкретных типа, которые выходят из него. Затем можно определить поведение и атрибуты на основе конкретного подтипа и, следовательно, включить полиморфные аспекты в эти отношения.

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

Следующий большой разрыв возникает в случае отношений «многие ко многим».

Отношения многие ко многим

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

class Author
{
private Book aBook;
//getters and setters for the aBook attribute
//other attributes and methods
}

class Book
{
private Author anAuthor;
//getters and setters for the anAuthor attribute
//other attributes and methods
}

 

Отношения «многие ко многим» между Автором и Книгой означают переход от одной сущности к коллекции. Класс Author и Book может быть следующим:

class Author
{
private Set<Book> books;
//getters and setters for the books attribute
//other attributes and methods
}

class Book
{
private Set<Author> authors;
//getters and setters for the authors attribute
//other attributes and methods
}

 

В реляционном мире изменения не так просты. Отношения «один к одному» или «один ко многим» могут быть реализованы с использованием ограничений внешнего ключа, но отношения «многие ко многим» требуют создания отдельной таблицы для этой цели. Эти таблицы, называемые таблицами сопоставления или связями, не имеют аналогов в мире объектов.

До сих пор мы видели три случая расхождения между миром объектов и миром реляционных сущностей. Хотя список может продолжаться какое-то время, я ограничу его лишь еще одним случаем, и это идентичность.

Концепция идентичности

Реляционные таблицы идентифицируют каждый объект как строку в таблице. Каждая строка обычно уникально идентифицируется с использованием первичного ключа. В объектах, хотя вещи не так ясно. У объектов могут быть два разных взгляда на идентичность. Два объекта, указывающие на одну и ту же ссылку на объект, можно считать равными. В то же время может быть установлено равенство, если два объекта соответствуют друг другу по значениям своих атрибутов.

Тогда возникает вопрос: как вы отображаете разные типы идентичностей и создаете общее чувство уникальности? Об этом позаботятся Hibernate и другие инструменты ORM. Hibernate также устраняет пробелы, о которых я упоминал ранее.

Увидев несколько расхождений между миром объектов и реляционными базами данных, давайте увидим, как Hibernate сглаживает вещи для нас.

Основы гибернации

Чтобы начать говорить об интеграции Flex и Hibernate, давайте подготовимся, рассмотрев вместе несколько важных концепций и способов использования Hibernate. Это не введение в Hibernate. Если вы хотите сначала перейти к базовому учебнику по Hibernate, я бы порекомендовал вам перейти на www.hibernate.org и прочитать первые несколько учебников, доступных на этом сайте.

На этом этапе, возможно, будет хорошей идеей загрузить копию Hibernate Core с сайта www.hibernate.org . На момент написания этой статьи последней стабильной версией является версия 3.3.2.GA. Hibernate состоит из набора продуктов, которые расширяют основные функции ORM, включая поддержку аннотаций Java 5, поддержку диспетчера сущностей для JPA, проверку и поиск, среди прочего. Для целей этой статьи вам понадобится только Hibernate Core.

Hibernate ожидает, что его сущности будут Plain Old Java Objects (POJO). Единственное требование состоит в том, чтобы POJO определяли конструктор без аргументов и определяли методы получения и установки для его личных атрибутов. Конструктор без аргументов используется для создания экземпляров Hibernate с использованием отражения Java.

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

Если бы вы использовали Hibernate для сохранения объекта Author из приложения каталога компьютерных книг, которое я собираюсь использовать в этой статье, вы сначала должны определить файл сопоставления, чтобы сообщить hibernate, как этот объект Author связан с соответствующими таблицами в базе данных. Класс Автор выглядит следующим образом:

class Author
{
public Author()
{
}
private int authorId;
private String name;
private String email;
//getters and setters for the attributes
}

 

Соответствующая таблица (представленная здесь с использованием DDL) выглядит следующим образом:

create table authors (
author_id INT NOT NULL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(75)
);

 

Отображение файлов в спящем режиме следует стандартному соглашению об именах. Файл сопоставления для объекта Author будет Author.hbm.xml. Вы можете использовать альтернативное соглашение об именах, но если вы это сделаете, убедитесь, что Hibernate настроен для него соответствующим образом. Содержимое Author.hbm.xml выглядит следующим образом:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Author" table="authors">
<id name="authorId" column="author_id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="email" />
</class>
</hibernate-mapping>

 

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

После того, как вы определили классы Author, Book и Publisher, их базовые таблицы и установили отношения с помощью файлов отображения Hibernate, вы готовы настроить сам Hibernate и заставить его работать. Hibernate можно настроить с помощью hibernate.properties или hibernate.cfg.xml. Вы также можете программно настроить Hibernate, если это то, что вы предпочитаете.

Я буду настраивать Hibernate, используя hibernate.cfg.xml. Hibernate.cfg.xml в нашем конкретном случае выглядит следующим образом:

<?xml version=’1.0’ encoding=’utf-8’?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/
book_catalog</property>
<property name="connection.username">root</property>
<property name="connection.password">specify the password here</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!-- Enable Hibernate’s automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.
NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping resource="Author.hbm.xml"/>
<mapping resource="Book.hbm.xml"/>
<mapping resource="Publisher.hbm.xml"/>

</session-factory>
</hibernate-configuration>

 

Вы заметите, что MySQL используется, и Hibernate был настроен на отображение всего базового SQL, который он генерирует и запускает от нашего имени. После настройки ресурсов вы можете загружать и хранить объекты.

Транзакции гибернации, которые включают загрузку и хранение объектов, включают в себя концепцию сеанса. Статический класс SessionFactory в Hibernate может использоваться для создания экземпляра сеанса. Затем сеанс можно использовать для запуска транзакции, а также для загрузки и сохранения объектов. Обычно хорошей идеей является создание утилиты для предоставления доступа к настроенному экземпляру SessionFactory. Вы можете сделать это, создав служебный класс HibernateUtil, который может быть следующим:

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();

private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

}

Предполагается, что у вас установлен jar Hibernate Core и добавлен в ваш путь к классам для компиляции вышеуказанного класса. На этом этапе вы можете загружать и хранить объекты. Если вам нужно было написать код для хранения новой сущности Author, чье имя и адрес электронной почты были вам известны, вы могли бы сделать следующее:

import org.hibernate.Session;
import java.util.*;
import somepackage.Author;
import org.hibernate.tutorial.util.HibernateUtil;

public class AuthorManager {

public static void main(String[] args) {
AuthorManager mgr = new AuthorManager();

if (args[0].equals("store")) {
mgr.createAndStoreAuthor("an author", "[email protected]");
}
HibernateUtil.getSessionFactory().close();
}

private void createAndStoreEvent(String name, String email) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Author anAuthor = new Author();
anAuthor.setName(name);
anAuthor.setEmail(email);
session.save(anAuthor);
session.getTransaction().commit();
}
}

 

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

Далее я иллюстрирую, как Flex и Hibernate могут использоваться вместе.

Интеграция Flex и Hibernate

Первым важным компонентом, необходимым для интеграции Flex и Hibernate, является посредник удаленного взаимодействия, который облегчит обмен объектами из Java в AS3 и обратно, соответствующим образом переводя их при перемещении по проводам. Это означает, что если вы поклонник слабой связи посредством обмена данными JSON или XML через конечные точки на основе REST, то настоящая интеграция Flex и Hibernate не будет соответствовать вашим предпочтениям.

Для платформы Java доступно несколько коммерческих и библиотек с открытым исходным кодом, среди которых можно выделить следующие:

  • LifeCycle Data Services (LCDS) — коммерческий продукт от Adobe
  • BlazeDS — альтернатива LCDS с открытым исходным кодом от Adobe

  • GraniteDS — библиотека удаленного взаимодействия с открытым исходным кодом
  • WebORB — еще одна библиотека удаленного взаимодействия с открытым исходным кодом

LCDS — отличный выбор для интеграции Flex и Hibernate, поскольку это мощный масштабируемый продукт, который включает в себя надежный Hibernate Assembler для обеспечения поддержки большинства желаемых функций, включая следующие:


  • Ленивая загрузка

  • Инкрементное обновление

  • Соблюдение стандартной JPA и семантики Hibernate
  • Неинвазивная добавленная стоимость

 Однако LCDS является коммерческим программным обеспечением, и вам необходимо приобрести лицензию на продукт, чтобы использовать его в большой производственной среде. Альтернативой LCDS является BlazeDS, альтернатива с открытым исходным кодом. BlazeDS предоставляет те же преимущества, что и LCDS, в том, что касается удаленной поддержки, но он не включает встроенный адаптер для Hibernate. Это не конец пути, хотя для BlazeDS доступно несколько адаптеров с открытым исходным кодом для Hibernate. В этой статье я рассмотрю один такой адаптер с BlazeDS и использую его для иллюстрации случая эффективной интеграции Flex и Hibernate. Это позволит вам легко загружать части программного обеспечения и играть с ним после прочтения этой статьи. (Вы также можете скачать и играть с LCDS для экспериментов).

Наивный шаблон интеграции

 Многие разработчики подходят к проблеме интеграции Flex и Hibernate с учетом уровня обслуживания. Они планируют создать сервисный уровень Java, который расположен поверх слоя Hibernate для взаимодействия с объектами Hibernate.  Сервисный уровень, в свою очередь, передает объекты или, что еще хуже, его альтернативные представления, клиенту Flex.

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

В некоторых ситуациях классы уровня обслуживания становятся конечными точками удаленного взаимодействия Flex и настраиваются таким образом с помощью BlazeDS или других продуктов удаленного взаимодействия. С BlazeDS это означает, что JavaAdapter по умолчанию означает не обмениваться POJO с аналогами AS3, обрабатывающими объекты Hibernate. JavaAdapter не знает, что конкретный POJO является объектом Hibernate, поэтому он не применяет никаких специальных правил при их маршалинге по проводам. Hibernate возвращает постоянные сущности и их коллекции со встроенным прокси-сервером, который, как следует из названия, находится вместо реальных данных. Прокси-сервер помогает лениво загружать наборы данных и обеспечивает эффективное управление объектами и их коллекциями. Эти объекты и их коллекции находятся в JVM. Когда вы интегрируете эти постоянные слои в приложение Flex,Вы открываете эти объекты и их коллекции для языка и среды, выходящей за рамки их действия.

POJO при перехвате сериализатором преобразуются из объектов Java в представления AMF перед их отправкой по проводам. Когда эти представления AMF достигают Flash Player, они восстанавливаются в объекты AS3. Во время сериализации из Java в AMF сериализатор охотно выбирает все постоянные объекты Hibernate и отправляет их по сети. Прокси-серверы Hibernate заменяются данными, на которых они стоят. Это нарушает семантику отложенной загрузки, делая идею прокси бесполезной. Поэтому требуется специальный адаптер для Hibernate.

 

Шаблон клонирования и слияния

‘‘Clone and Merge Transfer Pattern’’ is a common design pattern involved in creating an ideal Hibernate adapter. It preserves the proxy characteristics of Hibernate entities and their collections while keeping the standard behavior of the essential serialization and de-serialization mechanism between Flex and Java intact. Diagram 1 shows the “Clone and Merge Transfer Pattern” pictorially.

 

Diagram 1: Clone and Merge Transfer Pattern

 

The main idioms in this pattern are the clone and merge operations. On the way from the Java server side to the Flex client, a persistent object with proxy-based references is cloned, and the clone is sent to the serializer-deserializer, which in turn converts it into an AS3 object. This object reaches the Flex client. In the reverse direction, an AS3 object, after being converted to Java, is merged back to the original persistent object. One important requirement for the merge operation to work successfully is that you keep a copy of the original object when it’s cloned. This copy can be maintained on the server or within the class locally.

When the copy of the object is stored on the server, the HTTP session seems like the best place for it. Keeping an application scoped and shared areas may make the object visible beyond its legitimate owners.

When the copy is maintained locally, you need to have a structure within the class for it. This is where you require entities to extend specific classes that accommodate for this structure. One could leverage

Aspect-Oriented Programming (AOP) to induce such behavior at runtime and keep persistent objects from extending a specific class or have them adhere to a specific API.

With that said, let’s look at one such open source adapter that can be leveraged for effective integration of Flex and Hibernate. The one I choose for this article is called Gilead.

Using Gilead

Gilead, as a project existed as ‘‘hibernate4gwt’’ for a while. From late 2008, it has included adapters for both GWT and BlazeDS (for Flex). To explore Gilead-specific features, let’s download and configure the adapter. To download the latest Gilead build, go to the project’s site on SourceForge. You can also navigate to this website form the Gilead home page, which points to http://noon.gilead.free.fr/gilead.

The latest stable release of Gilead, at the time of writing this article, is version 1.3.0.1169.

In order to use Gilead add its blazeds related jars to the classpath of your Flex and Java application. When using Flash Builder, opt for the joint Java/Flex project and point to the blazeds.war file as the Flex WAR file. Copy the Gilead Flex BlazeDS Hibernate adapter jar files to the WEB-INF/lib folder.

Then configure the adapter in remoting-config.xml as follows:

<adapters>
<adapter-definition id="persistent-adapter"
class="net.sf.gilead.blazeds.adapter.PersistentAdapter" >
<properties>
<persistence-factory>
<class>net.sf.gilead.sample.server.ApplicationContext</class>
<singleton>true</singleton>
<method>getSessionFactory</method>
</persistence-factory>
</properties>
</adapter-definition>
</adapters>

Gilead also has a PersistentMessagingAdapter that extends the ActionScriptAdapter, a messaging adapter.

The persistence adapter needs to get hold of a Hibernate session during the course of its operations. Hibernate sessions are created using a session factory, as shown earlier in this example. The preceding adapter configuration shows one way to specify the session factory. Within the persistence-factory property the following elements are specified:

  • singleton — A Boolean flag, which when true, appends a call to getInstance() before a call to the factory method is made
  • method — The factory method that instantiates or returns an existing session instance

 

Alternatively, within Java EE environments you could leverage JNDI. Gilead also supports JPA and allows for the additional elements for configuring the entity manager. First, you create the entities on the server side.

Once Gilead is configured you are ready to use it. The next step in to create your server side entities. The server side entities could be POJOs as shown earlier. When you want to restrict persistent objects to Java bean–style POJOs only, you need to either save a copy of the class on the server before it’s cloned or use the dynamic proxy, available in Gilead. Gilead uses the HTTP session to save the object copy when you choose to go with a server-centric stateful way of saving this information. This could pose scalability challenges as increasing number of entities are saved in the session.

An alternative to storing persistent objects in the session or using dynamic proxies, is to save a copy in the class itself. This requires persistent Hibernate entities to extend specific classes, which according to purists imposes unnatural contracts on the POJOs. When using this option the persist entity needs to extend Gilead’s LightEntity as follows:

import net.sf.gilead.pojo.java5.LightEntity;

class Author extends LightEntity implements Serializable
{
public Author()
{
}
//private static final long serialVersionUID = <generate one>;

private int authorId;
private String name;
private String email;
//getters and setters for the attributes
}

 

For Gilead’s LightEntity to be recognizable on the Flex client, you need to extend the corresponding AS3 object with Gilead’s client side LightEntity class, which is as follows:

package
{
import net.sf.gilead.pojo.actionscript.LightEntity;
[RemoteClass(alias="Author")]
[Managed]
public class Author extends LightEntity
{
public int authorId;
public String name;
public String email;
}
}

 

At this point, we could go on to create the entire application and see Gilead in use but I would leave that for a later exercise. The basic concepts are established and that is what we had set out to understand.

Conclusion

Although this article touches a number of different topics, I hope you are well grounded in the fundamentals of effective Flex and Hibernate integration. Using Flex and Hibernate together has its advantages and could be a way to achieve effective persistence in Rich Internet Applications (RIA). While commercial products like LCDS have robust built-in solutions to make Flex and Hibernate work together, options like BlazeDS could be combined with open source adapters for it to achieve the same. Gilead is one such option. Another exists in dpHibernate  and yet another is in the making and accessible at http://code.google.com/p/dsadapters/.

Besides, the style of integration depicted in this article, there is additional scope of creating managed data managers and client side entity managers for ORM and server agnostic semantics. That could possibly be a topic for a following discussion.

Also, lazy loading has its advantages especially when a network of objects is accessed but remember that it imposes more round tripping the server for population of the proxy objects with their real counterparts. Therefore it is advisable that you leverage lazy loading but with prudence and avoid it when you suspect the added benefits are minimal.

I understand many of you desire, more than the fundamentals that this article offers and prefer to have complete working examples. If that is the case, then hold on for a bit, till my new free ebook on Flex and Hibernate becomes available. Keep an eye on www.justflexup.com/flexandhibernate. If you don’t have the patience for it possibly buy my book on BlazeDS: Professional BlazeDS (Wiley, 2009) for some additional details.

 

References

1 Active record pattern — http://en.wikipedia.org/wiki/Active_record_pattern