Почему консоль Google Datastore ведет себя иначе, чем Java-библиотека GAE для Datastore? - PullRequest
0 голосов
/ 11 мая 2018

У меня есть приложение Google App Engine + Java, которое успешно работает в течение многих лет (с использованием JDO + хранилище данных для постоянного хранения), и у меня не было проблем ( время от времени и неохотно ) обновление свойствасущность в консоли Google Datastore вручную.

Недавно (возможно, последние 2-3 месяца) я заметил изменение в поведении, которое нарушает наше приложение.Я не понимаю точно, что идет не так или как мы могли справиться с этим.

Итак, мой вопрос: почему он ведет себя по-разному и что я могу с этим поделать?

Позвольте мне сначала попытаться объяснить поведение, которое я наблюдаю, а затем показать мой наименьший возможный повторяющийся контрольный пример..

Предположим, у вас был простой класс персистентности:

@PersistenceCapable
public class Account implements Serializable {

@Persistent private ShortBlob testShortBlob;
@Persistent private String name;
// ...etc...

}

Если в прошлом я редактировал имя через веб-консоль Datastore, он работал бы, как и ожидалось, поле имени изменилось бы ивсе остальное будет работать нормально.

Сейчас я наблюдаю такое поведение: после сохранения сущности через консоль я больше не могу запрашивать и загружать сущность в JDO, я получаю:

java.lang.ClassCastException: com.google.appengine.api.datastore.Blob cannot be cast to com.google.appengine.api.datastore.ShortBlob

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

Этот тестовый пример будет копироватьпроблема:

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
// this one really is a ShortBlob - will load fine in JDO
Entity account = new Entity("Account", "123");
account.setProperty("name", "Test Name");
account.setUnindexedProperty("testShortBlob", new ShortBlob("blah".getBytes()));

datastore.put(account);
// this one really is not a ShortBlob, its a blob - it will fail for the same reason I am seeing in production.
account = new Entity("Account", "124");
account.setProperty("name", "Test Name 2");
account.setUnindexedProperty("testShortBlob", new Blob("blah".getBytes()));
datastore.put(account);

// then load the entity via JDO

 try {
    accountFromJdo = pm.getObjectById(Account.class, key);
  } catch (Exception ex) {
    System.out.println("We get here, the object won't load with the ClassCast Exception");
  }

Так вот в чем проблема, но почему сохранение через консоль облачного хранилища данных заменяет ShortBlob на Blob?

Мой обходной путь в настоящее время заключается в том, чтобы установить для полей ShortBlob значение null в консоли хранилища данных, что позволит загружать объект.Но это отстой, если данные в BLOB-объекте важны!

Обновление:

Я проводил дополнительное тестирование, используя низкоуровневый JSON API, чтобы увидетьесли бы я мог увидеть разницу в необработанных ответах JSON до и после сохранения объекта через консоль.Хорошая новость в том, что я могу!

Перед редактированием сущности через консоль поле shortBlob, сохраненное в хранилище данных через интерфейс JDO App Engine, будет выглядеть так:

        },
        "testShortBlob": {
          "blobValue": "tNp7MfsjhdfjkahsdvfkjhsdvfIItWyzy6glmIrow4WWhRPbhQ/U+MGX3opVvpxu"
        },

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

        },
        "testShortBlob": {
          "blobValue": "tNp7MfsjhdfjkahsdvfkjhsdvfIItWyzy6glmIrow4WWhRPbhQ/U+MGX3opVvpxu",
          "excludeFromIndexes": true
        },

Незначительная разница, но я думаю, что это важно, согласно документы Java ShortBlob проиндексированы, а Blob нет.

enter image description here

Итак, я думаю, что мой вопрос сейчас таков: почему редактирование сущности через консоль Cloud Datastore изменяет индексированный статус полей BLOB-объектов?

1 Ответ

0 голосов
/ 11 мая 2018

Спасибо за подробный вопрос и отладку.Это кажется подозрительным.Я прослежу, чтобы https://issuetracker.google.com/issues/79547492 был назначен правильной команде.

Что касается обходных путей:

JSON API, который вы заметили, это Cloud Datastore API v1 существует множество клиентских библиотек , которые облегчают доступ к ним.

Этот API можно использовать для транзакционного чтения / изменения / записи сущностей.В вашем случае это позволит вам выполнить нужные преобразования.Кроме того, внесение изменений через JDO также будет работать.

...