Search code examples
androidormliteforeign-collection

How to deal with OrmLite ForeignCollection Fields in Android with GSON models


So, I have a few OrmLite 4.41 model classes which are initially being populated by GSON (simplified for clarity)

public class Crag {
  @DatabaseField(id=true) private int id;
  @ForeignCollectionField(eager=true, maxEagerLevel=2) @SerializedName("CragLocations")
  private Collection<CragLocation> cragLocations;
}

public class CragLocation {
    @DatabaseField(id=true) private int id;
    @DatabaseField private int locationType;
    @DatabaseField(foreign=true, foreignAutoCreate=true, foreignAutoRefresh=true)
    private Crag crag;  
    @DatabaseField(foreign=true, foreignAutoCreate=true, foreignAutoRefresh=true)
    private Location location;
}

public class Location {
    @DatabaseField(id=true) private int id;
    @DatabaseField private BigDecimal latitude;
    @DatabaseField private BigDecimal longitude;
}

I'm then testing that things are happening as I expect...

@Test
public void canFindById() {
    Crag expected = ObjectMother.getCrag431();
    _repo.createOrUpdate(template431);
    Crag actual = _repo.getCragById(431);
    assertThat(actual, equalTo(template431));
}

and they aren't equal... why not? because in the object created by GSON (in ObjectMother.getCrag431()) the cragLocations field of Crag is an ArrayList and in that loaded by OrmLite it is an EagerForeignCollection

Am I missing a trick here? Is there a way to tell OrmLite what type I want that Collection to be? Should I just have a method that returns the collection as an arraylist and test for equality on that?

Thanks in advance


Solution

  • Is there a way to tell OrmLite what type I want that Collection to be?

    There is no way to do this. When your Crag is returned by ORMLite, it is either going to be an EagerForeignCollection or LazyForeignCollection.

    Should I just have a method that returns the collection as an arraylist and test for equality on that?

    I assume in your Crag.equals(...) method, you are testing for equality for the cragLocations field as this.cragLocations.equals(other.cragLocations). This is not going to work because, as you guess, they are different types.

    If you need to test equality you can extract both of them as an array. Something like:

    Array.equals(
        this.cragLocations.toArray(new CragLocation[this.cragLocations.size()]),
        other.cragLocations.toArray(new CragLocation[this.cragLocations.size()]));