Google App Engine и JDO: транзакция не записывается в хранилище данных

Мы используем GAE с JDO2.3 и имеем этот код:

public void submit_job (HttpSession session, BlobKey blobKey) throws Exception {
  // START TRANSACTION
  PersistenceManager pm = PMF.get().getPersistenceManager();
  Transaction tx = pm.currentTransaction();
  tx.begin();

  // GET JOB AND MEMBER FROM DATASTORE
  Key jobKey = (Key)session.getAttribute("jobkey");
  String userName = session.getAttribute("username").toString();

  Job job = pm.getObjectById(Job.class, jobKey);
  Member m = pm.getObjectById(Member.class, username);

  // STORE JOB INFORMATION IN DATASTORE
  Date now = new Date();
  job.caricature = blobKey;
  job.whenSubmitted = now;
  job.whenFinished = now;
  pm.makePersistent(job);
  pm.flush();
  log.warning("submit_job: updating job " + job.key);

  // UPDATE MEMBER INFORMATION
  m.numSubmittedJobs++;
  pm.makePersistent(m);
  pm.flush();    
  log.warning("submit_job: updating user " + username);

  // COMPLETE TRANSACTION
  tx.commit();
  pm.close();
  log.warning("transaction completed? " + !tx.isActive());
}

Симптомы:

  • исключение не генерируется, все работает нормально
  • в конце транзакция завершена должным образом («транзакция завершена? истина»)
  • следующие запросы могут читать обновленные данные из объектов Member и Job

НО

  • информация не отображается в диспетчере хранилища данных
  • после перезапуска экземпляра объекты JDO имеют свои старые значения. ВСЕ ИЗМЕНЕНИЯ УТЕРЯНЫ.

Вот наш jdoconfig.xml:

<?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.api.jdo.JDOPersistenceManagerFactory"/>
       <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"/>
       <property name="datanucleus.appengine.singletonPMFForName" value="true"/>
       <property name="datanucleus.appengine.datastoreEnableXGTransactions" value="true"/>
   </persistence-manager-factory>
</jdoconfig>

и persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">

    <persistence-unit name="transactions-optional">
        <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
        <properties>
            <property name="datanucleus.NontransactionalRead" value="true"/>
            <property name="datanucleus.NontransactionalWrite" value="true"/>
            <property name="datanucleus.ConnectionURL" value="appengine"/>
        </properties>
    </persistence-unit>
</persistence>

Любая помощь приветствуется, мы уже вложили много усилий в эту тему, но пока не можем ее решить.

Спасибо!


person a.barth    schedule 06.05.2013    source источник


Ответы (1)


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

И посмотрите журнал тоже, так как он сообщает вам, что происходит

person DataNucleus    schedule 06.05.2013
comment
Да, конечно, я ожидаю, что изменения будут сохранены, как только я явным образом вызову makePersist (). Но спасибо за подсказку, попробую :) - person a.barth; 06.05.2013
comment
Спасибо, приятель, я создал класс @PersistenceAware, и все изменения теперь правильно записываются в хранилище данных. - person a.barth; 06.05.2013