clouway / twig-persist

twig-persist
0 stars 3 forks source link

Loading Entity with not initialized property of type Set<?> #9

Open IvanLazov opened 10 years ago

IvanLazov commented 10 years ago

Twig does't load correctly entities which have not initialized property of type Set<?>

For example:

We have the following entity

public static class SetContainer {

    public Set<Long> values; // not initialized

    public SetContainer() {
    }

    public SetContainer(Set<Long> values) {
      this.values = values;
    }

    public Set<Long> getValues() {
      return values;
    }
  }

Then we store and load the entity

@Test
  public void storeAndLoadSet() {

    SetContainer collection = new SetContainer(Sets.newHashSet(100l, 200l, 300l));

    ObjectDatastore datastore = new AnnotationObjectDatastore();

    Key key = datastore.store(collection);

    datastore.disassociateAll();

    SetContainer loaded = datastore.load(key);

    Assert.assertThat(loaded.getValues().size(), is(3));
  }

The following test will fail because the returned object contains an empty set of values.

This is due to the fact that when Twig converts each Entity property to the corresponsing field (type and value) it doesn't have a convertor for ArrayList (i.e. collections that are not initiliazed are represented as ArrayLists). If the collection was initialized to new HashSet(), then twig finds and use the following converter DirectObjectConverter.

There are two solutions:

1) Register a new convert for ArrayList<?> to Set<?> in the Twig's MapConverters (Cannot guarantee that the behavior will be the same)

public class MapConverters {

...

public static class EntryListToSet implements Converter<List<?>, Set<?>> {

    @Override
    public Set<?> convert(List<?> source) {

      Set<Object> entries = new HashSet<Object>();
      for (Object o : source) {
        entries.add(o);
      }

      return entries;
    }
  }

public static void registerAll(ConverterRegistry converter) {
    converter.register(new EntrySetToMap());
    converter.register(new EntryListToSet());
}
...

2) Make sure that if we have an Entity with property of type Set<?> it is initialized.