Невозможно сохранить объекты в GAE JDO - PullRequest
5 голосов
/ 03 мая 2010

Я совершенно новый как для JDO, так и для GAE, и изо всех сил пытался заставить мой уровень данных вообще сохранить любой код!

Проблемы, с которыми я сталкиваюсь, могут быть очень простыми, но я просто не могу найти какой-либо способ, независимо от того, какое решение я пытаюсь.

Во-первых, проблема: (немного упрощена, но все еще содержит всю необходимую информацию) Моя модель данных такова:

User:
    (primary key)
    String emailID
    String firstName

Car:
    (primary key)
    User user
    (primary key)
    String registration
    String model

Это была начальная модель данных. Я реализовал объект CarPK для получения составного первичного ключа пользователя и регистрации. Однако это столкнулось с различными проблемами. (Который я сохраню для другого времени / вопроса)

Затем я изменил дизайн как таковой: Пользователь: (без изменений)

Car:
(primary key)
String fauxPK (here fauxPK = user.getEmailID() + SEP + registration)
User user
String registration
String model

Это прекрасно работает для пользователя и может вставлять и извлекать пользовательские объекты. Однако, когда я пытаюсь вставить объект автомобиля, я получаю следующую ошибку:

"Cannot have a java.lang.String primary key and be a child object"

Found the following helpful link about it:
http://stackoverflow.com/questions/2063467/persist-list-of-objects

Перешел по предложенной там ссылке, которая объясняет, как создавать Ключи, однако они продолжают говорить о «Группах сущностей» и «Родителях Entity Group». Но я не могу найти какие-либо статьи или сайты, которые объясняют, что такое «Entity Group» или «Entity Group Parent»

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

Так что я был бы признателен за любые документы (даже если они огромные), которые охватывают все эти моменты и, предпочтительно, имеют несколько примеров, выходящих за рамки самого базового моделирования данных.

И спасибо, что прочитали такой длинный пост:)

Ответы [ 2 ]

13 голосов
/ 04 мая 2010

Боюсь, вам не понравится ответ. GAE JDO должен использоваться очень особым образом и чревато ограничениями, которые вы должны соблюдать, чтобы использовать его эффективно. Читайте документы вперед и назад. Для решения проблемы, с которой вы столкнулись сейчас, вам, вероятно, нужно прочитать этот раздел несколько раз:

http://code.google.com/appengine/docs/java/datastore/relationships.html

GAE JDO имеет принадлежащие и неизвестные отношения. См. Документацию выше для примеров , принадлежащих против , не принадлежащих . Я полагаю, что вы хотите, чтобы Car и User имели отношения не принадлежащие . Обратите внимание на это откровение в документации по Google App Engine о неизвестных отношениях:

http://code.google.com/appengine/docs/java/datastore/relationships.html#Unowned_Relationships

В дополнение к собственным отношениям, JDO API также предоставляет возможность управления неизвестными отношениями. Реализация JDO в App Engine еще не реализовала эту возможность , но не беспокойтесь, вы все еще можете управлять этими отношениями, используя значения Key вместо экземпляров (или коллекций экземпляров) ваших модельных объектов.

По сути, это означает, что для использования GAE JDO не следует использовать прямую ссылку для неизвестных отношений , как между классами Car и User. Скорее, вы должны использовать косвенные ссылки между ними, то есть в Car должно быть поле для ключа пользователя, а не прямая ссылка на самого пользователя. Некоторые проблемы возникают из-за того, что GAE JDO не может справиться с тем, как вы моделируете эти отношения в коде.

Аскер продолжает:

Пошла по предложенной там ссылке, которая объясняет, как создавать Ключи, однако они продолжают говорить о "Группы сущностей" и "Родители группы сущностей". Но я не могу найти какие-либо статьи или сайты, которые объясняют, что такое «Entity Group» или «Entity Group Parent»

Группа сущностей - график объектов, которые изначально были сохранены вместе . Например, поскольку Car ссылается непосредственно на пользователя, когда вы сохраняете данный экземпляр Car в первый раз, вы также сохраняете экземпляр пользователя, к которому он относится, и этот экземпляр Car и этот экземпляр пользователя будут частью одного и того же объекта. группа. Если этот экземпляр пользователя уже был сохранен либо самостоятельно, либо как часть другого экземпляра Car, то этот экземпляр пользователя уже находится в другой группе сущностей. Предполагается, что «собственные» отношения находятся в одной группе объектов. Обратите внимание, что транзакции GAE JDO могут изменять только 1 группу объектов - больше не будет возникать исключение.

Родитель группы объектов - постоянный класс верхнего / корневого ("родительского") класса s. В приведенном выше примере, когда вы сохраняете данный экземпляр Car в первый раз, вы также сохраняете экземпляр User, к которому он относится. Экземпляр Car является родителем группы сущностей. «Принадлежащий» «дочерний» класс, такой как User, встраивает ключ своего родителя (Car) в собственный (User) ключ. Если вы должны извлечь экземпляр Car из базы данных, а затем попытаться получить доступ к пользователю, к которому относится этот автомобиль, то GAE JDO будет использовать ключ Car для поиска соответствующего пользователя (поскольку в ключе целевого пользователя встроен ключ родительского автомобиля как часть собственного ключа).

Asker получил это сообщение об ошибке:

"Не может иметь первичный ключ java.lang.String и быть дочерним объектом"

Примечание это утверждение в документах :

Дочерний класс должен иметь поле ключа, тип которого может содержать информацию о родительском ключе: либо ключ, либо значение ключа, закодированное в виде строки. Информацию о ключевых типах полей см. В разделе «Создание данных: ключи».

Это означает, что «дочерние» классы должны использовать определенные типы ключей (т. Е. Ключи, которые способны инкапсулировать ключ своего родителя в ключ ребенка). Long и String подходят для родителей группы сущностей классов, то есть классов, не являющихся дочерними. Однако «дочерние» классы должны использовать тип ключа Key или Key encoded as String. Сообщение об ошибке указывает, что класс Car ссылается на класс User, как если бы он был «дочерним» «дочерним» классом, и поэтому класс User должен использовать тип ключа, подходящий для дочернего класса, но класс User не использует ключ тип, соответствующий ребенку (не закодированная строка).

Исправление для непосредственной проблемы заключается в том, чтобы смоделировать Car и User как отношения unowned , изменив Car с прямой ссылки на пользователя вместо косвенной ссылки с сохранением ключа соответствующего пользователя. , Общее исправление, скорее всего, будет включать тщательный анализ того, как вписать вашу объектную модель в структуру GAE JDO (как только вы изучите документы, чтобы попытаться понять это). Это, вероятно, будет включать необходимость вручную управлять некоторыми отношениями между классами.

Если это утешит, я сам решаю такие же проблемы с GAE JDO (у меня даже есть класс автомобилей!).

0 голосов
/ 03 мая 2010
...