My favorites | Português | Sign in

Como usar a JDO com o Google App Engine

A JDO (Objetos de dados Java) é uma interface padrão para armazenar objetos que contêm dados em um banco de dados. O padrão define as interfaces para anotar objetos Java, recuperar objetos com consultas e interagir com um banco de dados usando transações. Um aplicativo que usa a interface JDO pode trabalhar com tipos diferentes de banco de dados sem usar qualquer código específico para eles, incluindo banco de dados relacionais, hierárquicos e de objetos. Como acontece com outros padrões de interface, a JDO facilita o transporte do seu aplicativo entre as diferentes soluções de armazenamento.

O SDK para Java do Google App Engine inclui uma implementação da JDO 2.3 para o armazenamento de dados dos Google App Engine. A implementação é baseada no DataNucleus Access Platform, a implementação de referência de software livre para a JDO 2.3.

Para obter mais informações sobre a JDO, consulte a documentação do Access Platform 1.1. Em especial, consulte "Mapeamento da JDO" e "API da JDO".

Como definir uma JDO

Para usar a JDO para acessar o armazenamento de dados, um aplicativo do Google App Engine precisa do seguinte:

  • Os JARs do plug-in do Google App Engine para JDO e DataNucleus devem estar no diretório war/WEB-INF/lib/ do aplicativo.
  • Uma arquivo de configuração chamado jdoconfig.xml deve estar no diretório war/WEB-INF/classes/META-INF/ do aplicativo, com uma configuração que diz para a JDO usar o armazenamento de dados do Google App Engine.
  • O processo de criação do projeto deve realizar uma etapa de "aprimoramento" pós-compilatório nas classes de dados compilados para associá-las à implementação JDO.

Se você estiver usando o plug-in do Google para o Eclipse não precisa se preocupar com esses três itens. O novo assistente de projetos coloca os JARs do plug-in do Google App Engine para JDO e DataNucleus no local correto e cria o arquivo jdoconfig.xml. O processo de criação realiza a etapa de "aprimoramento" automaticamente.

Se estiver usando o Apache Ant para criar o seu projeto, você pode usar uma tarefa Ant incluída no SDK para realizar a etapa de aprimoramento. Copie os JARs e crie o arquivo de configuração quando configurar o seu projeto. Consulte Como usar o Apache Ant para obter mais informações sobre a tarefa Ant.

Como copiar os JARs

A JDO e os JARs do armazenamento de dados estão incluídos no SDK para Java do Google App Engine. Eles estão no diretório appengine-java-sdk/lib/user/orm/.

Copie os JARs para o diretório war/WEB-INF/lib/ do seu aplicativo.

Certifique-se de que o appengine-api.jar também esteja no diretório war/WEB-INF/lib/ (isso já pode ter sido feito ao criar o projeto). O plug-in do Google App Engine para DataNucleus usa esse JAR para acessar o armazenamento de dados.

Criação do arquivo jdoconfig.xml

A interface JDO precisa de um arquivo de configuração chamado jdoconfig.xml no diretório war/WEB-INF/classes/META-INF/ do aplicativo. Ele pode ser criado diretamente nesse local ou o processo de criação pode copiá-lo de um diretório de origem.

Crie o arquivo com o seguinte conteúdo:

<?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>

Como aprimorar as classes de dados

A JDO usa uma etapa de "aprimoramento" pós-compilatório no processo de criação para associar classes de dados à implementação JDO.

Se você estiver usando o Eclipse, o plug-in do Google App Engine para o Eclipse faz essa etapa automaticamente na criação.

Se estiver usando o Apache Ant, o SDK inclui uma tarefa Ant para isso. Consulte Como usar o Apache Ant para obter mais informações sobre a tarefa Ant.

A etapa de aprimoramento pode ser realizada em classes compiladas a partir da linha de comando com o seguinte comando:

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

O caminho de classe deve conter o JAR appengine-tools-api.jar do diretório appengine-java-sdk/lib/, bem como todas as suas classes de dados.

Para obter mais informações sobre o aprimorador bytecode do DataNucleus, consulte a documentação do DataNucleus.

Como obter uma instância PersistenceManager

Um aplicativo interage com a JDO usando uma instância da classe PersistenceManager. Essa instância pode ser obtida ao instanciar e chamar um método em uma instância da classe PersistenceManagerFactory. A fábrica usa a configuração JDO para criar instâncias PersistenceManager.

Como uma instância PersistenceManagerFactory demora para inicializar, um aplicativo deve reutilizar uma única instância. Para reforçar isso, uma exceção é gerada se o aplicativo instancia mais de uma PersistenceManagerFactory (com o mesmo nome de configuração). Uma maneira fácil de gerenciar a instância PersistenceManagerFactory é criando uma única classe empacotadora com uma instância estática, conforme mostrado abaixo:

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;
    }
}

O aplicativo usa a instância factory para criar uma instância PersistenceManager para cada solicitação que acessa o armazenamento de dados.

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

import PMF;

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

A PersistenceManager pode ser usada para armazenar, atualizar e excluir objetos de dados, e realizar consultas ao armazenamento de dados

Quando terminar de trabalhar com a instância PersistenceManager, chame o método close(). É um erro usar a instância PersistenceManager depois de chamar o seu método close().

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

Recursos da JDO não suportados

Os recursos abaixo da interface JDO não são suportados pela implementação do Google App Engine:

  • Relacionamentos não proprietários. Os relacionamentos não proprietários podem ser implementados usando valores Key explícitos. A sintaxe da JDO para relacionamentos não proprietários pode ter suporte em uma versão futura.
  • Relacionamentos proprietários de vários-para-vários.
  • Consultas "associadas". Não é possível usar um campo de uma entidade filho em um filtro ao executar uma consulta no tipo pai. Observe que você pode testar o campo de relacionamento do pai diretamente na consulta usando uma chave.
  • O agrupamento JDOQL e outras consultas agregadas.
  • Consultas polimórficas. Não é possível consultar uma classe para obter instâncias de uma subclasse. Cada classe é representada no armazenamento de dados por um tipo de entidade separado.
  • IdentityType.DATASTORE para a anotação @PersistenceCapable. É suportado somente IdentityType.APPLICATION.
  • No momento, há um bug impedindo que os campos persistentes das superclasses sejam salvos no armazenamento de dados. Isso será corrigido em uma versão futura.