Избранное | Русский | Войти

Использование JDO с App Engine

Объекты данных Java (JDO) представляют собой стандартный интерфейс для хранения объектов данных в реляционной базе данных. Стандарт определяет интерфейсы для аннотации объектов Java, получения объектов с помощью запросов и взаимодействия с базой данных посредством транзакций. Приложение, использующее интерфейс JDO, может работать с различными базами данных, не используя их код, включая реляционные, иерархические и объектные базы данных. Как и при использовании других стандартных интерфейсов, JDO упрощает портирование приложения между различными решениями для хранения.

Java SDK App Engine включает реализацию JPA 2.3 для хранилища данных App Engine. Реализация основывается на DataNucleus Access Platform, справочной реализации с открытым исходным кодом для JDO 2.3.

Дополнительные сведения о JDO можно найти в документации по Access Platform 1.1. В частности, посмотрите разделы "JDO Mapping" и "JDO API".

Настройка JDO

Чтобы использовать JDO для доступа к хранилищу данных, App Engine нужно выполнить следующие действия:

  • JAR JDO и плагин DataNucleus для App Engine должны находиться в каталоге приложения war/WEB-INF/lib/.
  • Файл конфигурации jdoconfig.xml должен находиться в каталоге приложения war/WEB-INF/classes/META-INF/ и содержать конфигурацию, предписывающую JDO использовать хранилище данных App Engine.
  • После компиляции классов данных в процессе сборки проекта должны выполняться действия по их "улучшению". Это позволит их связать с реализацией JDO.

При использовании плагина Google для Eclipse эти действия выполнять не нужно. Новый мастер проектов помещает JAR JDO и плагин DataNucleus для App Engine в нужное местоположение и создает файл jdoconfig.xml. В процессе сборки "улучшение" осуществляется автоматически.

Если вы используете для сборки проекта Apache Ant, можно использовать задание Ant, включенное в SDK, для выполнения этапа улучшения. При настройке проекта нужно скопировать JAR и создать файл конфигурации. Подробнее задание Ant описано в статье Использование Apache Ant.

Копирование JAR

JAR JPA и хранилища данных включены в SDK Java App Engine. Они находятся в каталоге appengine-java-sdk/lib/user/orm/.

Скопируйте JAR в каталог приложения war/WEB-INF/lib/.

Убедитесь, что appengine-api.jar также находится в каталоге war/WEB-INF/lib/. (Он мог быть туда помещен при создании проекта.) Плагин DataNucleus для App Engine использует этот JAR для доступа к хранилищу данных.

Создание файла jdoconfig.xml

Интерфейсу JDO нужен файл конфигурации jdoconfig.xml в каталоге приложения war/WEB-INF/classes/META-INF/. Этот файл можно создать прямо в этом месте или скопировать его из исходного каталога в процессе сборки.

Создайте файл со следующим содержанием:

<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">

    <persistence-manager-factory name="transactions-optional">
        <property name="javax.jdo.PersistenceManagerFactoryClass"
            value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
        <property name="javax.jdo.option.ConnectionURL" value="appengine"/>
        <property name="javax.jdo.option.NontransactionalRead" value="true"/>
        <property name="javax.jdo.option.NontransactionalWrite" value="true"/>
        <property name="javax.jdo.option.RetainValues" value="true"/>
        <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
    </persistence-manager-factory>
</jdoconfig>

Улучшение классов данных

После компиляции классов данных в процессе сборки проекта должны выполняться действия по их "улучшению". Это позволит связать эти классы данных с реализацией JDO.

При использовании Eclipse плагин Google для Eclipse выполняет эти действия автоматически в процессе сборки.

Если используется Apache Ant, SDK включает задание Ant, выполняющее этот этап. Дополнительную информацию о задании Ant можно получить в статье Использование Apache Ant.

Можно улучшить скомпилированные классы, выполнив в командной строке следующую команду :

java -cp classpath com.google.appengine.tools.enhancer.Enhance class-files

Параметр classpath должен содержать JAR appengine-tools-api.jar из каталога appengine-java-sdk/lib/, а также все классы данных.

Дополнительные сведения об улучшении байтового кода с помощью DataNucleus можно найти в документации по DataNucleus.

Получение экземпляра класса PersistenceManager

Приложение взаимодействует с JDO с помощью экземпляра класса PersistenceManager . Его можно получить, создав экземпляр и вызвав метода для экземпляра класса PersistenceManagerFactory. Чтобы создать экземпляры класса PersistenceManager, фабрика использует конфигурацию JDO.

Поскольку для инициализации экземпляра класса PersistenceManagerFactory требуется время, приложения может неоднократно использовать один экземпляр. С этой целью при попытке создания приложением нескольких экземпляров класса PersistenceManagerFactory (с одним названием для конфигурации) возникает исключение. Проще всего управлять экземпляром класса PersistenceManagerFactory, создав отдельный класс-оболочку для статического экземпляра следующим образом:

PMF.java

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {
    private static final PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");

    private PMF() {}

    public static PersistenceManagerFactory get() {
        return pmfInstance;
    }
}

Приложение использует экземпляр фабрики для создания одного экземпляра класса PersistenceManager для каждого запроса к хранилищу данных.

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

import PMF;

// ...
    PersistenceManager pm = PMF.get().getPersistenceManager();

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

Завершив работу с экземпляром класса PersistenceManager, следует вызвать его метод close(). Его нельзя использовать после вызова метода close().

    try {
        // ... do stuff with pm ...
    } finally {
        pm.close();
    }

Неподдерживаемые функции JDO

Реализация App Engine не поддерживает следующие функции интерфейса JDO:

  • Отношения без владельца. Эти отношения можно реализовать с помощью явных значений Key. Не исключено, что синтаксис JDO для них будет поддерживаться в следующем выпуске.
  • Отношения "многие ко многим" с владельцем.
  • Синтаксис contains() для фильтров запросов по полям коллекций. С помощью фильтра равенства collection == "value" можно проверить, содержит ли свойство с несколькими значениями (поле коллекции) какое-либо значение.
  • Запросы "объединения". При выполнении запроса по родительскому типу нельзя использовать поле дочернего объекта в фильтре. Обратите внимание, что поле отношений родителя можно проверить прямо в запросе с помощью ключа.
  • Группировка JDOQL и другие общие запросы.
  • Полиморфные запросы. Нельзя выполнять запрос класса для получения экземпляров подкласса. Каждый класс представлен в хранилище данных отдельным типом объекта.
  • IdentityType.DATASTORE для аннотации @PersistenceCapable. Поддерживается только IdentityType.APPLICATION.
  • На данный момент найдена ошибка, не позволяющая сохранять постоянные поля суперклассов в хранилище данных. Она будет исправлена в будущем выпуске.