2

是否可以通过 Robospice/ORMlite 缓存嵌套(2-3 级嵌套)对象(外部字段)? https://groups.google.com/forum/#!msg/robospice/VGLB3-vM3Ug/-piOac212HYJ - 你可以读到这是可能的,但不幸的是我无法实现。

这是我的源代码:

@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 除外)。你有什么建议吗?

4

1 回答 1

1

这更像是一个 ORM Lite 问题,而不是 RoboSpice 问题。

也许您可以将地址数据“嵌入”到俱乐部实体/表格中。

这个线程可能很有趣: Ormlite 中的一对一关系

如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.

于 2013-05-21T05:22:42.113 回答