Кэширование вложенных объектов в Robospice с помощью ORMLite
Можно ли кэшировать вложенные (2-3 уровня вложенности) объекты (чужие поля) через Robospice / ORMlite? https://groups.google.com/forum/ - там вы можете прочитать, что это возможно, но, к сожалению, я не могу этого достичь.
Вот мой исходный код:
@DatabaseTable(tableName = "city")
@JsonIgnoreProperties(ignoreUnknown = true)
public class City {
@DatabaseField(id = true)
@JsonProperty("id")
private long id;
@DatabaseField
@JsonProperty("name")
private String name;
@ForeignCollectionField(eager = true, maxEagerLevel = 3)
@JsonProperty("clubs")
private Collection<Club> clubs;
...
@DatabaseTable(tableName = "club")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Club {
@DatabaseField(id = true)
@JsonProperty("user_id")
private long id;
@DatabaseField
@JsonProperty("name")
private String name;
@DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "city_id", maxForeignAutoRefreshLevel = 2)
private City city;
@DatabaseField(foreign = true)
@JsonProperty("address")
private VenueAddress address;
...
@DatabaseTable(tableName = "address")
@JsonIgnoreProperties(ignoreUnknown = true)
public class VenueAddress {
@DatabaseField(id = true)
@JsonProperty("uid")
private long id;
@DatabaseField
@JsonProperty("street")
private String street;
@DatabaseField
@JsonProperty("street_number")
private String streetNumber;
@DatabaseField
@JsonProperty("country")
private String country;
@DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "club_id", maxForeignAutoRefreshLevel = 2)
private Club club;
...
И образец SpiceService:
public class SampleSpiceService extends SpringAndroidSpiceService {
private static final int WEBSERVICES_TIMEOUT = 10000;
@Override
public CacheManager createCacheManager(Application application) {
CacheManager cacheManager = new CacheManager();
List<Class<?>> classCollection = new ArrayList<Class<?>>();
// add persisted classes to class collection
classCollection.add(VenueAddress.class);
classCollection.add(City.class);
classCollection.add(Club.class);
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper(application,
"sample_database.db", 5);
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory(
application, databaseHelper, classCollection);
cacheManager.addPersister(inDatabaseObjectPersisterFactory);
return cacheManager;
}
@Override
public RestTemplate createRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
// set timeout for requests
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setReadTimeout(WEBSERVICES_TIMEOUT);
httpRequestFactory.setConnectTimeout(WEBSERVICES_TIMEOUT);
restTemplate.setRequestFactory(httpRequestFactory);
MappingJacksonHttpMessageConverter messageConverter = new MappingJacksonHttpMessageConverter();
restTemplate.getMessageConverters().add(messageConverter);
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
return restTemplate;
}
}
И когда я выбираю объект City из кэша, он имеет коллекцию клубов, но VenueAddress в каждом клубе имеет нулевые поля (кроме id). Есть ли у вас какие-либо советы?
1 ответ
Это скорее вопрос ORM Lite, чем вопрос RoboSpice.
Может быть, вы могли бы "встраивать" адресные данные в клубные права / таблицы.
Эта тема может представлять интерес: отношения один-к-одному в Ormlite
Проблема может исходить отсюда, как указано в документах ormlite:
foreignAutoRefresh
Задайте для этого параметра значение true (по умолчанию false), чтобы внешнее поле автоматически обновлялось при запросе объекта. По умолчанию это просто поле идентификатора в извлеченном объекте и вызывающая сторона вызывает обновление в правильном DAO. Если для этого параметра установлено значение true, то при запросе объекта будет выполнен отдельный вызов базы данных для загрузки полей стороннего объекта через внутренний DAO. ПРИМЕЧАНИЕ. Это не приведет к автоматическому созданию постороннего объекта, если вы создадите объект, для которого установлено это поле.
ПРИМЕЧАНИЕ. Это создаст другой объект DAO внутри, поэтому устройства с небольшим объемом памяти могут захотеть вызвать обновление вручную.
ПРИМЕЧАНИЕ. Для защиты от рекурсии есть несколько мест, где автоматическое обновление было ограничено. Если вы автоматически обновляете класс, для которого само поле с ForeignAutoRefresh установлено значение true или если вы автоматически обновляете класс с чужой коллекцией, в обоих случаях результирующее поле будет иметь значение null и не будет автоматически обновляться. Вы всегда можете вызвать обновление на поле напрямую, если вам это нужно.