Проблема с отсоединением всего графа объектов в GAE-J с помощью JDO
-
18-09-2019 - |
Вопрос
Я пытаюсь загрузить полный объектный график для пользователя, который содержит коллекцию колод, которая затем содержит коллекцию карт, как например:Пользователь:
@PersistenceCapable(detachable = "true")
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
@FetchGroup(name = "decks", members = { @Persistent(name =
"_Decks") })
public abstract class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
protected Key _ID;
@Persistent
protected String _UniqueIdentifier;
@Persistent(mappedBy = "_Owner")
@Element(dependent = "true")
protected Set<Deck> _Decks;
protected User()
{
}
}
В каждой Колоде есть коллекция карт, как таковая:
@PersistenceCapable(detachable = "true")
@FetchGroup(name = "cards", members = { @Persistent(name =
"_Cards") })
public class Deck {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _ID;
@Persistent
String _Name;
@Persistent(mappedBy = "_Parent")
@Element(dependent = "true")
private Set<Card> _Cards = new HashSet<Card>();
@Persistent
private Set<String> _Tags = new HashSet<String>();
@Persistent
private User _Owner;
}
И, наконец, каждая карточка:
@PersistenceCapable
public class Card {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _ID;
@Persistent
private Text _Question;
@Persistent
private Text _Answer;
@Persistent
private Deck _Parent;
}
Я пытаюсь извлечь, а затем отсоединить весь объектный граф.Я вижу в отладчике, что он загружается нормально, но затем, когда я добираюсь до отсоединения, я не могу сделать ничего, кроме загрузки пользовательского объекта.(Нет Колод, нет карт).Сначала я попытался без транзакции просто "коснуться" всех полей прикрепленного объекта перед отсоединением, но это не помогло.Затем я попытался добавить все в выборку по умолчанию group, но это просто сгенерировало предупреждения о том, что GAE не поддерживает объединения.Я попытался установить максимальную глубину выборки для плана выборки равным -1, но это не помогло.Наконец, я попытался использовать FetchGroups, как вы можете видеть выше, а затем выполнить извлечение с помощью следующего кода:
PersistenceManager pm = _pmf.getPersistenceManager();
pm.setDetachAllOnCommit(true);
pm.getFetchPlan().setGroup("decks");
pm.getFetchPlan().setGroup("cards");
Transaction tx = pm.currentTransaction();
Query query = null;
try {
tx.begin();
query = pm.newQuery(GoogleAccountsUser.class); //Subclass of User
query.setFilter("_UniqueIdentifier == TheUser");
query.declareParameters("String TheUser");
List<User> results = (List<User>)query.execute(ID); //ID = Supplied
parameter
//TODO: Test for more than one result and throw
if(results.size() == 0)
{
tx.commit();
return null;
}
else
{
User usr = (User)results.get(0);
//usr = pm.detachCopy(usr);
tx.commit();
return usr;
}
} finally {
query.closeAll();
if (tx.isActive())
{
tx.rollback();
}
pm.close();
}
Это тоже не работает, и у меня заканчиваются идеи...
Решение
Я уверен, что чтение журнала (уровень отладки) сообщило бы вам намного больше, поскольку оно, безусловно, сообщает вам, когда происходит отсоединение чего-либо.Возможно, GAE / J не соблюдает отложенную загрузку при отсоединении ?DataNucleus сам по себе отлично работает со всеми другими хранилищами данных.
Зачем вызывать FetchPlan.setGroup(), когда это перезаписывает все существующие группы ?addGroup() имеет для меня больше смысла.