Question

Is it possible to cache nested (2-3 level of nesting) objects (foreign fields) via Robospice/ORMlite? https://groups.google.com/forum/#!msg/robospice/VGLB3-vM3Ug/-piOac212HYJ - there you can read that is possible, but unfortunatelly I can't achieve it.

Here is my source code:

@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;
...

And sample 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;
    }

}

And when I fetch City object from cache it has clubs collection, but VenueAddress in each Club has null fields (except id). Do you have any advices?

Était-ce utile?

La solution

This is more a ORM Lite question than a RoboSpice thing.

Maybe you could "embed" the address data inside the club entitiy/table.

This thread might be of interest : one-to-one relationship in Ormlite

The problem may come from here as stated in ormlite docs :

foreignAutoRefresh

Set this to be true (default false) to have a foreign field automagically refreshed when an object is queried. The default is to just have the ID field in the object retrieved and for the caller to call refresh on the correct DAO. If this is set to true then, when the object is queried, a separate database call will be made to load of the fields of the foreign object via an internal DAO. NOTE: this will not automagically create the foreign object if you create an object that has this field set.

NOTE: This will create another DAO object internally so low memory devices may want to call refresh by hand.

NOTE: To protect against recursion, there are a couple of places were auto-refreshing has been limited. If you are auto-refreshing a class that itself has field with foreignAutoRefresh set to true or if you are auto-refreshing a class with a foreign collection, in both cases the resulting field will be set to null and not auto-refreshed. You can always call refresh on the field directly if you need it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top