Hibernar no Google AppEngine

Estamos no processo de migração da ActivityInfo.org para o Google AppEngine e seu serviço Cloud SQL baseado em MySQL.

A experiência tem sido bastante simples, mas tivemos que fazer alguns ajustes para que o Hibernate funcionasse bem no AppEngine.

Primeiro, você deve desabilitar completamente o pool de conexão. Instâncias do CloudSQL são exibidas e desativadas para que você não possa manter uma conexão além da duração de uma solicitação. Isso pode ser feito por meio da configuração:

hibernate.connection.pool_size = 0

O segundo problema é o tempo de inicialização. Por padrão, o Hibernate 3.6 (a versão que estamos usando) irá escanear seu classpath procurando por classes anotadas com @Entity. Isso não é um grande problema quando você abre novas instâncias uma vez por dia ou assim, mas as instâncias do AppEngine aparecem e são desativadas com bastante frequência.

O Hibernate estava levando mais de 30 segundos para inicializar, o que significa que muitas solicitações de aquecimento – as primeiras solicitações do usuário para uma nova instância – estavam expirando.

Conseguimos contornar isso fornecendo a lista de classes explicitamente usando a API Ejb3Configuration:

Ejb3Configuration config = new Ejb3Configuration();
config
.setProperty("hibernate.connection.driver_class",
"com.google.appengine.api.rdbms.AppEngineDriver");
config
.setProperty("hibernate.connection.url",
"jdbc:google:rdbms://domain.com:project:instance/db");
config
.setProperty("hibernate.connection.pool_size", "0");
config
.addAnnotatedClass(MyEntity.class);
config
.addAnnotatedClass(MyEntity2.class);
return config.buildEntityManagerFactory();

Estávamos usando persistence.xml para configuração, mas não consegui descobrir como desabilitar a verificação do caminho da classe sem recorrer à API Ejb3Configuration.