Failed to serialize object (using Room DB) to json string using Gson

how to store objects in room database
how to store arraylist in room database
json to room android
android room list of objects
android room save nested objects
save image in room database android
typeconverter room android

I have a class Item (see below) in which I have used some Room db annotations. It also has a nested class named ItemInfo. Both of these classes have an empty constructor.

The problem is that when I try to serialize an object of Item class, app crashes with the following error:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.android.carrymates, PID: 18526
              java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible
                  at java.lang.reflect.AccessibleObject.setAccessible0(AccessibleObject.java:133)
                  at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:119)
                  at com.google.gson.internal.reflect.PreJava9ReflectionAccessor.makeAccessible(PreJava9ReflectionAccessor.java:31)
                  at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:103)
                  at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
                  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
                  at com.google.gson.Gson.getAdapter(Gson.java:458)
                  at com.google.gson.Gson.toJson(Gson.java:696)
                  at com.google.gson.Gson.toJson(Gson.java:683)
                  at com.google.gson.Gson.toJson(Gson.java:638)
                  at com.google.gson.Gson.toJson(Gson.java:618)
                  ... more log (irrelevant to question asked)

Item.java

@Entity(tableName = "items", indices = {@Index(value = {"id"}, unique = true), @Index(value = {"owner", "type"})})
public class Item {

    @PrimaryKey
    @NonNull
    String id="";

   //...rest fields are int, boolean and String only

    @Embedded
    ItemInfo itemInfo; // see ItemInfo


    public Item() {

   }


    // ...getters and setters

    @IgnoreExtraProperties
    public static class ItemInfo {

        //...fields are int, boolean and String only

        public ItemInfo() {

        }

        //...getters and setters
    }
}

My guess is that Room DB annotations are adding at least one object of type java.lang.reflect.Method which Gson is unable to serialize.

Below is the code I am using to serialize Item object to json string, where item is a object of class Item with non-null values of fields of type String and ItemInfo.

Gson gson = new Gson();
String result = gson.toJson(item); // crash begins from here

How do I address this problem? I expect at least a workaround solution.

I can suggest you use different objects for different goals (storing in a Room db and serializing to json).

You need to have an interface of your Item entity:

public interface Item {

    int getId();

    //other fields
}

Then you need a specific implementation for a Room db entity. What you actually already have, but need make same refactoring:

@Entity(tableName = "items", indices = {@Index(value = {"id"}, unique = true), @Index(value = {"owner", "type"})})
public class RoomItem implements Item {

    @PrimaryKey
    @NonNull
    private int id;

    //other fields

    public RoomItem() {
    }

    public RoomItem(Item item) {
        id = item.getId();
    }

    @Override
    public int getId() {
        return 0;
    }

    @Override
    public void setId(int id) {
        this.id = id;
    }

    //other getters and setters
}

Plus you need to get rid of the inner static class ItemInfo and make it in a separate .java file.

And finally, you need a specific implementation for a Gson entity:

public class GsonItem implements Item {

    private final int id;

    public GsonItem(Item origin) {
        id = origin.getId();
    }

    @Override
    public int getId() {
        return id;
    }
}

In this case, you will able to use it like this without any issues:

Gson gson = new Gson();
String result = gson.toJson(new GsonItem(item));

Yes, this approach leads you to write a little bit more code, but lack of unexpected issues like yours definitely cost the effort!

Failed to serialize object (using Room DB) to json string using Gson, I have a class Item (see below) in which I have used some Room db annotations. It also has a nested class named ItemInfo. Both of these  Serialize Realm objects to JSON using GSON. GitHub Gist: instantly share code, notes, and snippets.

Try this please: this code snipped is working properly

import android.arch.persistence.room.Embedded;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;

import com.google.firebase.database.IgnoreExtraProperties;

@Entity(tableName = "items", indices = {@Index(value = {"id"}, unique = true), @Index(value = {"owner", "type"})})
public class Item {

    @PrimaryKey
    @NonNull
    String id="";

    //...rest fields are int, boolean and String only

    @Embedded
    ItemInfo itemInfo; // see ItemInfo


    public Item() {

    }


    // ...getters and setters

    @IgnoreExtraProperties
    public static class ItemInfo {

        //...fields are int, boolean and String only

        public ItemInfo() {

        }

        int prop1;
        String id="";
        //...getters and setters
    }
}

note the dependencies snipped too please

implementation 'com.google.firebase:firebase-core:16.0.3'
implementation "com.google.firebase:firebase-database:16.0.1"

// Arch
implementation "android.arch.core:runtime:1.1.1"
implementation "android.arch.core:common:1.1.1"

implementation 'android.arch.persistence.room:runtime:1.1.1';
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1';

and the implementation:

        Item item = new Item();

        item.id = "Rover";
        item.itemInfo = new Item.ItemInfo();
        item.itemInfo.id = "asd";
        item.itemInfo.prop1 = 1;

        Gson gson = new Gson();

        String json = gson.toJson(item); // here json ={"id":"Rover","itemInfo":{"id":"asd","prop1":1}}

Gson 2.8,.6 fails to serialize/deserialize SparseArray on Android 10 , I'm using Gson in my @TypeConverter class to convert SparseArray objects into json String to be saved in Room database. Here is how I do it:  // Serialization: // <Type>RealmProxy objects are created by the Realm annotation processor. They are used to control. // access to the actual data instead of storing them in fields and it is therefore them we need to register a.

normally i get output when i try this,

public class Car { 

    public String brand = null;

    public int    doors = 0;

}


Car car = new Car();

car.brand = "Rover";

car.doors = 5;

Gson gson = new Gson();

String json = gson.toJson(car);

checkout this : http://tutorials.jenkov.com/java-json/gson.html

google/gson: A Java serialization/deserialization library to , It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects including pre-existing objects that you do not​  public IEnumerable<User> GetAll() { using (Database db = new Database()) { return db.Users.ToList(); } } Answers: When it comes to returning data back to the consumer from Web Api (or any other web service for that matter), I highly recommend not passing back entities that come from a database.

do not nest these classes, in order to use the @Embedded annotation:

@Entity(
    tableName = "items",
    indices = {
        @Index(value = {"id"}, unique = true), 
        @Index(value = {"owner", "type"})
    }
)
public class Item {

    @PrimaryKey
    @ColumnInfo(name = "id")
    String id = null;

    @Embedded
    ItemInfo itemInfo;

    public Item() {

    }
}

@Entity(tableName = "item_info")
public class ItemInfo {

    public ItemInfo() {

    }

    ...
}

also see this answer, concerning GSON exclusion strategies (which might be required for itemInfo)

or simply add these fields directly into class Item, in order to serialize them all at once -

in order not to add more complexity than required, which only cause issues down the road.

Gson, public class UserSimple { String name; String email; boolean Basically, in JSON we just create a new object with  Gson is a Java Library widely used to convert Java Objects into their JSON representation and vice versa. Getting Started. Let's start by creating a new Java project. We can call it "InterfaceSerialization". We need to add the gson library in our project in order for us to use it. If you are using Maven, add the latest version of gson to the POM file.

Disclaimer:

I'm not aware of what RoomDB does with @Entity classes (though it looks like RoomDB uses subclasses rather than classes written by you).

Also I run the test on JVM

But I can suggest you to use @Expose:

public class GsonTest {

  private static class SampleModel {
    @Expose
    private int i;

    private Method method;

    @Expose
    private Nested nested = new Nested();
  }

  private static class Nested {
    @Expose
    private String a = "my string";
  }

  @Test
  public void failsWithMethodField() throws Exception {
    assertThrows(Exception.class, () -> {
      SampleModel sampleModel = new SampleModel();
      sampleModel.i = 10;
      sampleModel.method = Object.class.getDeclaredMethod("equals", Object.class);
      Gson gson = new Gson();
      gson.toJson(sampleModel);
    });
  }

  @Test
  public void withExposedDoesNotFail() {
    assertDoesNotThrow(() -> {
      SampleModel sampleModel = new SampleModel();
      sampleModel.method = Object.class.getDeclaredMethod("equals", Object.class);
      Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
      String json = gson.toJson(sampleModel);
      System.out.println(json); // {"i":0,"nested":{"a":"my string"}}
    });
  }
}

The essential part is to configure Gson with excludeFieldsWithoutExposeAnnotation option:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

Then mark all fields that should be used when serializing and deserializing with @Expose annotation.

When nullability lies: A cautionary tale, How does a non-null property wind up null in Kotlin? Let's find out! That class declares, “The placeName property is a String that can't be null .” Need more I'​ve got a Room entity like so: It got worse: The exception left the database locked. The UI Gson makes slurping in JSON as objects painless. Let's serialize a Java object to a Json file and then read that Json file to get the object back. In this example, we've created a Student class. We'll create a student.json file which will have a json representation of Student object. Example. Create a Java class file named GsonTester in C:\>GSON_WORKSPACE. File - GsonTester.java

Json assert ignore fields, You can also serialize to a JSON-encoded string using dumps . API Reference How to To do that I have a text field on the object I create which holds the JSON string. NON_NULL This implementation uses a clean-room implementation of the org. JsonPath. Ignore or exclude field in Gson by leveraging Java modifiers​. Free source code and tutorials for Software developers and Architects.; Updated: 30 Nov 2017

Java Code Examples com.google.gson.JsonArray, This page provides Java code examples for com.google.gson. insObjs); JsonArray retArr = new JsonArray(); for (String retCol : this. mkCall(opUrl, db.​gson. public JsonElement serialize(ServerStatusResponse. the download/​parsing fails * * @return An array of objects with information about the stored files * */ public  There are a lot of frameworks for deserializing json to a java object such as json-rpc, Gson, Flexjson and a whole lots of other open source libraries. Of all the libraries mentioned I would in

Create reactive mobile apps in a fraction of the time, Use them like regular java objects Dog dog = new Dog(); dog. developer tool, built so you can easily manage the Realm Database and Realm Platform. public class User extends RealmObject { private String name; private int age; @​Ignore When it comes to parsing JSON using standard libraries like Moshi, GSON or  Serialization and Deserialization of Generic Types using Gson TypeToken If a java class is generic type and we are using it with google Gson to JSON serialization and deserilization, Gson has no way to know what type of class has been passed to generic class. To fix this problem, Gson introduced TypeToken.

Comments
  • Could you post the serialization code?
  • @OlmanCarballoTellez see?
  • What type is the type field? Is it really just int, boolean, and String fields or are there any types of type Class in there too?
  • Yes, rest fields are int, boolean and String only.
  • String result = gson.toJson(item); What's in item ?, it must be java objects, for eg Car car = new Car(); car.brand = "Rover"; car.doors = 5; Gson gson = new Gson(); String json = gson.toJson(car);