ActiveAndroid icon indicating copy to clipboard operation
ActiveAndroid copied to clipboard

Arrays not supported?

Open pteale-tuneit opened this issue 12 years ago • 18 comments

Are simple arrays (other than byte) not supported?

Here is a simple example, first I have defined a test class..

@Table(name = "Tests")
public static class Test extends Model {

    public Test() {super();}

    @Column(name = "Names")
    public String[] names = new String[4];

    public static Test getTest() {
        return new Select().from(Test.class).executeSingle();
    }

    public static List<Test> getAll() {
        return new Select().from(Test.class).execute();
    }
}

Then I create a record and save it like this..

Test test = new Test(); test.names = new String[] {"Paul", "Ricardo", "Henry", "Robert"}; test.save();

When I try and get the values back the string array is null This also happens for any arrays of primitive types

pteale-tuneit avatar Jan 31 '14 11:01 pteale-tuneit

AA supports only String, Integer, Char, Enum, Date (java.sql and java.util), Long and another types that implements TypeSerializer

leonardoxh avatar Feb 28 '14 16:02 leonardoxh

There is no way to save arrays? :(

I need save a array... any idea?

philipesteiff avatar Apr 09 '14 21:04 philipesteiff

@philipesteiff What do your arrays look like? Just strings?

joshuapinter avatar Apr 09 '14 21:04 joshuapinter

Int[]

philipesteiff avatar Apr 09 '14 21:04 philipesteiff

Shouldn't be too bad if you create a custom TypeSerializer.

How comfortable are you with this? Otherwise, I can have a look tonight.

joshuapinter avatar Apr 09 '14 21:04 joshuapinter

I thought about having objects that represent the database and objects that represent the application.

Im a beginner in ActiveAndroid, I dont know how can i make a array with TypeSerializer. I changed my int[] to Integer[];

I just wish the Integer [] type of my object was maintained to avoid adjustments by code

philipesteiff avatar Apr 09 '14 21:04 philipesteiff

I've never had to do it before but it should be possible.

What kind of data are you storing in your Integer[] column?

joshuapinter avatar Apr 09 '14 21:04 joshuapinter

Numbers. But these are not saving :/

philipesteiff avatar Apr 09 '14 21:04 philipesteiff

Well, you're obviously saving Integers in your Integer[] column. ;)

But integers for what? Is there another way to architect it to avoid doing this?

joshuapinter avatar Apr 09 '14 21:04 joshuapinter

haha..

Maybe, i can change to String and save/get fields with Gson.

philipesteiff avatar Apr 09 '14 21:04 philipesteiff

Could be a good way to go. Let me know how it goes.

joshuapinter avatar Apr 09 '14 21:04 joshuapinter

Works! :) ..

But did not solve my problem, because I use this same object to make webservice requests. When object serialization by Gson converts: { myArray myArray: "[1, 2, 3, 4]" } --> "Quotes" are not recognized as array in webservice. :(

Here example:

public class Obj {

  @Column(name = "ColumnMyArray")
   String myArray; // "[ 1, 2, 3, 4]" :(

   public int[] getMyArray() {
        return new Gson.getGson().fromJson(myArray, int[].class);
    }

    public void setMyArray(int[] myArray) {
        this.myArray = new Gson.getGson().toJson(myArray);
    }


}

Is there any way that I can interfere when save() execute? Or force to save myArray serialized.

philipesteiff avatar Apr 10 '14 14:04 philipesteiff

Nice try, @philipesteiff. You're halfway there. I think the best bet is to have ActiveAndroid handle arrays better.

What web service are you using?

Can you create a simple app I can use as a test?

joshuapinter avatar Apr 10 '14 21:04 joshuapinter

Unfortunately cant release access to the company server. Not need to use the web service, just preserve the array type.

You're thinking about modifying the ActiveAndroid to work better with arrays?

I'm two days thinking about a way how to solve this. If I fix in ActiveAndroid the Gson sends the wrong format, if I fix in Gson the ActiveAndroid not save.

philipesteiff avatar Apr 10 '14 21:04 philipesteiff

Yeah, I think it makes sense to handle basic arrays in AA, like int[] and string[].

joshuapinter avatar Apr 10 '14 21:04 joshuapinter

I had the same problem with a boolean array and I solved it using a TypeSerializer:

public class BooleanArraySerializer extends TypeSerializer {

    @Override
    public Class<?> getDeserializedType() {
        return boolean[].class;
    }

    @Override
    public Class<?> getSerializedType() {
        return String.class;
    }

    @Override
    public String serialize(Object data) {
        if (data == null) {
            return null;
        }
        return toString((boolean[])data);
    }

    @Override
    public boolean[] deserialize(Object data) {
        if (data == null) {
            return null;
        }
        return toArray((String)data);
    }


    private boolean[] toArray(String value) {
        String[] values = value.split(",");
        boolean[] result = new boolean[values.length];
        for (int i = 0; i < values.length; i++) {
            result[i] = Boolean.parseBoolean(values[i]);
        }
        return result;
    }

    private String toString(boolean[] values) {
        String result = "";
        for (int i = 0; i < values.length; i++) {
            result += String.valueOf(values[i]);
            if (i < values.length - 1) {
                result += ",";
            }
        }
        return result;
    }
}

angelpinheiro avatar Oct 10 '14 12:10 angelpinheiro

is there any workaround to support List<Object> with TypeSerializer?

harsewak avatar Apr 08 '17 08:04 harsewak

After trying bit hard for some hours, I have found a work around for List<Object to serialize

public abstract class BaseGsonSerializer extends TypeSerializer {

    private Gson gson;

    public BaseGsonSerializer() {
        this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    }

    @DebugLog
    @Override
    public Class<?> getSerializedType() {
        return String.class;
    }

    @Override
    @DebugLog
    public Class<?> getDeserializedType() {
        return TypeToken.get(getTypeDeserialize()).getRawType();
    }

    @Override
    public Object serialize(Object data) {
        if (data != null) {
            return gson.toJson(data);
        }
        return null;
    }

    @Override
    public Object deserialize(Object data) {
        if (data != null) {
            return gson.fromJson(data.toString(), getTypeDeserialize());
        }
        return null;
    }

    protected abstract Type getTypeDeserialize();

}

Use of BaseGsonSerializer

public class PriceListSerializer extends BaseGsonSerializer {

    protected Type getTypeDeserialize() {
        return new TypeToken<List<Price>>() {
        }.getType();
    }
}

I am not sure how expensive this workaround could be! suggestions are most welcome

harsewak avatar Apr 08 '17 18:04 harsewak