I am converting an object to JSON using com.google.code.gson:gson:2.2.4 library by using code:
String json = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PROTECTED).create().toJson(object);
And in the JSON string "serialVersionUID" is added automatically with Long value even if it is not in a model class. I just want to remove serialVersionUID from JSON.
I found this answer. Basically, the serialVersionUID is added by InstantRun, disabling InstantRun solved the issue for me.
One way to get around this is to use GsonBuilder.excludeFieldsWithoutExposeAnnotation then use the #Expose annotation to explicitly mark what is or isn't (de)serialized.
public class SomeClass {
private int field1 = 2;
#Expose private int field2 = 6;
#Expose #SerializedName ("foo") private int field3 = 12;
}
gives you {"field2":6, "foo":12}. The field field1 is excluded because it isn't annotated with #Expose.
Personally, I always use the GsonBuilder.excludeFieldsWithoutExposeAnnotation because it filters out any generated fields (like the Instant Run comment above). If you didn't annotate it with #Expose, it won't be serialized/deserialized.
Another way is to declare the field as transient.
Related
I'm using Retrofit 2 with a SimpleXmlConverter and I am facing an issue when creating a Soap Request Object, that is basically an element with 4 element children each one of them being different datatypes.
Here is the XML output I want to produce. The element order must be respected:
<prf:container>
<prf:aaa>111111111</prf:aaa>
<prf:bbb>true</prf:bbb>
<prf:element>
<prf:ddd>50</prf:ddd>
<prf:eee>false</prf:eee>
</prf:element>
<prf:ccc>textcontent</prf:ccc>
</prf:container>
Now, here is my Android Class, Container.java, representing the Soap Request Object that will be serialized:
#Root (name = "prf:container")
#Order(elements={"prf:aaa", "prf:bbb", "prf:element", "prf:ccc"})
public class Container {
#Element (name = "prf:aaa")
private int aaa;
#Element(name = "prf:bbb")
private boolean bbb;
#Element (name = "prf:element", required = false)
private MyElement myElement;
#Element (name = "prf:ccc", required = false)
private String ccc;
}
According to the Simple XML framework documentation:
By default serialization of fields is done in declaration order.
However, in Android, this is not true, at least in some cases. No matter how I set the field declaration order in my Container class, the output has always the same element order. This is a known bug and as has been reported in other SO posts.
Nonetheless, there is a solution to this issue. The Order annotation.
Read more in the Javadoc.
My problem is that using the Order annotation in my case is not helping. Note that all my elements have a prefix on its name - prf:.
If I remove the prf prefix from all my element names, Order annotation will work properly, and force the XML Serialization to have the defined order. But the output elements won't have the prefix on its name.
But I really need my elements to have the prefix on its name, or else my request will have a 500 response. I also have to have the desired element order in my XML output.
Any solution to this?
Thank you
I know it has been a long item since you posted this question but, I would like to answer your question in case anyone faced the same issue. I solved the same issue by doing the following:
For the XML document to be prepared with the elements in the order you want and if the elements have a prefix, #Order annotation might not work in some cases. In your case, the prefix 'prf' mentioned in the #Order annotation for each element would not work to order them as you desired.
"By default serialization of fields is done in declaration order."
I don't believe this either, especially when you have prefixes for elements. So, I tried changing the Java variable names. I tried naming them in alphabetical order in the same way I needed them in the generated xml. So, in your case, you can change the variable names as follows:
#Root (name = "prf:container")
public class Container {
#Element (name = "prf:aaa")
private int element1;
#Element(name = "prf:bbb")
private boolean element2;
#Element (name = "prf:element", required = false)
private MyElement element3;
#Element (name = "prf:ccc", required = false)
private String element4;
}
This would form the xml document exactly as you wanted. You might wonder that if we change the variable names to be too generic, they are not representing what they actually are but, you can always have getters and setters. For example, in your case you can have:
public void setAaa(String aaa){
this.element1 = aaa;
}
public String getAaa(){
return element1;
}
In the same way you can always generate the classes with alphabetically ordered variables to make sure the generated xml has the elements in the desired format.
Maybe you using #Order with wrong syntax,Alphabetical order is not important. You can try:
#Root (name = "prf:container")
#Order(elements={"prf:container/prf:aaa", "prf:container/prf:bbb", "prf:container/prf:element", "prf:container/prf:ccc"})
public class Container {
#Element (name = "prf:aaa")
private int aaa;
#Element(name = "prf:bbb")
private boolean bbb;
#Element (name = "prf:element", required = false)
private MyElement myElement;
#Element (name = "prf:ccc", required = false)
private String ccc;
}
SimpleXML's auto ordering by alphabetical order is working. But on one condition: the type of those fields should be the same, usually for XML it is String. It took me long time to figure that out, I had different types, and ordering by name didn't work. Since I've changed all fields to String works like a charm.
#Root(name = "sch:CheckPaymentRequest", strict = true)
public class CheckPaymentData {
#Element(name = "sch:payId")
private String Aaa1;
#Element(name = "sch:fromCurrency")
private String Bbb2;
#Element(name = "sch:fromAmount")
private String Ccc3;
...}
I'm using Gson to serialize an Active Android model. The model class contains only primitives, and Gson should have no issues serializing it with the default settings. However, when I try, I get the error:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: <MyClass>. Forgot to register a type adapter?
I would really rather not write a type adapter for every one of my model classes, how can I get around this issue?
Figured it out. Of course, Active Android's base model class is adding fields that cannot be serialized by default. Those fields can be ignored using Gson's excluedFieldsWithoutExposeAnnotation() option, as follows:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(new Book());
Modify the class with the #Expose annotation to indicate which fields should be serialized:
#Table(name = "Foo")
public class Foo extends Model {
#Expose
#Column(name = "Name")
public String name;
#Expose
#Column(name = "Sort")
public int sort;
...
}
an easier way is to initialize your Gson as below to prevent serializing Final,Transient or Static fields
Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
.serializeNulls()
.create();
How to save an ArrayList using ORMlite in android my model is as follows
class Model{
#DatabaseField
public String type = "";
#DatabaseField
public String name = "";
#DatabaseField
public Date dateTime = null;
#DatabaseField
ArrayList<Item> items = null;
}
And Item class has
class Item{
#DatabaseField
String itemName;
...
}
I am getting the following exception :
java.sql.SQLException: ORMLite can't store unknown class class
java.util.ArrayList for field 'items'. Serializable fields must specify
dataType=DataType.SERIALIZABLE
But when i specify my field as
#DatabaseField(dataType = DataType.SERIALIZABLE)
ArrayList<Item> items = null;
The compiler gives a error called field cannot be resolved please help me with this.
I've just changed the error message to be:
ORMLite does not know how to store class
java.util.ArrayList for field 'items'. Use another class, custom persister, or to serialize it use dataType=DataType.SERIALIZABLE
Maybe that makes more sense? ORMLite is trying to say that it doesn't know how to store lists in a field. If you want to store collection of items then maybe you should take a look at the foreign-collection documentation.
I read all documentation about orm lite, also looking on net but didn't find right answers. I want to execute this statement:
SELECT * from Drive where day_number=150;
I have class that represent table:
#DatabaseTable(tableName="Drive")
public class Drive{
#DatabaseField(generatedId=true)
private int drive_id;
#DatabaseField
private String start_time;
#DatabaseField
private String end_time;
#DatabaseField
private String price;
#DatabaseField
private String distance;
#DatabaseField
private String day_number;
#DatabaseField
private String week_number;
#DatabaseField
private String month;
getters and setters ...
}
When i run:
List<Drive> today = getHelper().getVoznjaDao().queryBuilder().where().
eq("day_number","150").query();
I get NullPointerExeption, and it's not because there is no record for 150 in database.
Please help i am desperate.
Your code looks fine in terms of the query-builder logic. I suspect that something to do with your wiring is incorrect however. In your comments you mention that the NPE happens on the query line.
List<Drive> today = getHelper().getVoznjaDao().queryBuilder().where().
eq("day_number","150").query();
Most likely this means that either:
getHelper() is returning a null helper instance
getVoznjaDao() is returning a null DAO
or there are bugs in ORMLite
today being null would not cause a NPE since it is not dereferenced on the line. Certainly a bug in ORMLite is not out of the question but I would first check with a debugger to see if the getHelper() or getVoznjaDao() calls are returning null. I suspect you will find the bug at that point.
Hello i am using ORMLite 4.33.
I have an entity class that gives me an error when trying to destroyTable:
E/AndroidRuntime(6715): java.lang.IllegalArgumentException: Field class
java.lang.String for field FieldType:name=udm,class=Prodotti is not valid
for data persister com.j256.ormlite.field.types.EnumStringType#40a3a2e0
here is the class
#DatabaseTable(tableName = "Prodotti")
public class Prodotti extends BaseDaoEnabled{
....
#DatabaseField(dataType = DataType.ENUM_STRING,
columnDefinition="VARCHAR(100) DEFAULT NULL")
//also tried #DatabaseField(dataType = DataType.ENUM_STRING)
private String udm;
...
}
I runned DatabaseConfigUtil to update the ormlite_config.txt, right now i'm thinking the only solution is to change the type of the field to String
ORMLite does not support database SQL enum columns which are only supported by a couple of database types. The ENUM_STRING is supposed to persist an enum type. Something like:
#DatabaseField
private OurEnum udm;
...
public enum OurEnum {
RED, GREEN, BLUE;
}
By default, ORMLite will then persist the enum as it's string value (RED, GREEN, BLUE) in a VARCHAR SQL field. If you have a String field then you should just let it be persisted as a STRING type. You can also use the DataType.ENUM_INTEGER if you want to store its value instead but that is not recommended for backwards compatibility reasons.
If you edit your questions to better explain what you are trying to accomplish, I can edit my answer to provide more information.