Обновление дочерних объектов в Google App Engine с использованием DataNucleus JDO - PullRequest
1 голос
/ 13 февраля 2011

Я потратил несколько часов, пытаясь разобраться с этим, и я просто не могу заставить мои дочерние сущности обновляться, несмотря на несколько предложений.Я внимательно изучил документы GAE и попытался поместить вещи в транзакции, попытался сделать их «принадлежащими» объектам и сделать их частью «группы извлечения по умолчанию».Объекты правильно сохраняются в хранилище данных после запуска фиктивного метода populateDatastore, описанного ниже, и я могу без проблем получить их из хранилища данных.Когда я делаю изменения, эти изменения не сохраняются, хотя я использую методы установки, поэтому JDO забирает изменения.Я не эксперт по Java, поэтому я могу делать что-то действительно явно неправильное и не вижу этого.

Родительский объект

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Parent {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent
  private String invitationCode;

  @Persistent(defaultFetchGroup = "true")
  private Child child;

  // additional ivars and getters and setters
}

Дочерний объект

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Response {

  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent(mappedBy = "child")
  private Parent parent;

  // additional ivars and getters and setters
}

У меня есть несколько методов для извлечения исохранить объекты.

public void persistParent(Parent p, boolean closeSession){
  manager = PMF.get().getPersistenceManager();
  manager.makePersistent(p);

  if(closeSession) {
    manager.close();
  }
}

public Transaction beginTransaction() {
  int retries = 3;
  manager = PMF.get().getPersistenceManager();
  Transaction tx = manager.currentTransaction();

  try {
    tx.begin();
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    return null;
  }
  catch(Exception e) {
    return null;
  }
  return tx;
}

public boolean endTransaction(Transaction tx) throws Exception {
  int retries = 3;
  try {
    tx.commit();
  }
  catch(ConcurrentModificationException e) {
if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(Exception e) {
    if (retries == 0) {
      throw e;
    }
    --retries;
  }
  finally {
    if(tx.isActive()) {
      tx.rollback();
    }
  }

  manager.close();

  return true;
}

public List<Parent> getParentWithID(String code, boolean closeSession) {
  Query q = PMF.get().getPersistenceManager().newQuery(Parent.class);
  q.setFilter("code == codeParam");
  q.declareParameters("String invitationCodeParam");

  List<Invitation> results = null;
  try {
    results = (List<Parent>) q.execute(code);
  } 
  finally {
    if(closeSession) {
      q.closeAll();
    }
  }

 return results;
 }

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

Child c = new Child(arg1, arg2, arg3);
c.setSomeIVarForChild(arg1);
p = new Parent(arg1, arg2, arg3);
p.getChildList().add(c);
rsvpDao.persistParent(p, true);

Ответы [ 3 ]

1 голос
/ 14 февраля 2011

Я не знаю точно, какова реализация позади "PMF.get ()", но в случае, если вы создаете новую PersistenceManagerFactory для каждого get () - в этом нет необходимости, вы можете просто держите его как статический член. Если это не проблема, попробуйте проверить, используете ли вы тот же PersistenceManager для извлечения и обновления объектов данных: это означает только один вызов PMF.get (). GetPersistenceManager () за всю операцию. Если вам нужно запросить объекты и затем сохранить их позже, используя другой PersistenceManager , вам следует detach

0 голосов
/ 19 марта 2015

Я добавил следующее, и это исправило мою проблему:

if(JDOHelper.getPersistenceManager(obj) != pm) {
    logger.error("JDOHelper.getPersistenceManager(obj) != pm  ->     JDOHelper.getPersistenceManager(obj)[" +     JDOHelper.getPersistenceManager(obj).toString() + "]"
                            + " pm[" + pm.toString() + "]");
                    detatchedJob =     JDOHelper.getPersistenceManager(obj).detachCopy(obj);
                    jobs.add(detatchedJob);
                } else {
                    detatchedJob = pm.detachCopy(obj);
                    jobs.add(detatchedJob);
                }
0 голосов
/ 20 декабря 2014

Проблема, с которой я столкнулся, заключалась в том, что первичным ключом моего родительского объекта был объект "Ключ".Переход на Лонг работал.Не уверен, что именно проблема и как это решило проблему, так как я новичок в Android и Gae

...