Save and retrieve Arraylists using ActiveAndroid ORM and Retrofit - java

I am using Retrofit and ActiveAndroid ORM in my application. I have the following Model class:
#Table(name = "formresource")
public class FormResource extends Model implements Serializable{
#Column(name="name")
#SerializedName("name")
#Expose
private String name;
#Column
#SerializedName("resources")
#Expose
private List<FormResource> resources = new ArrayList<FormResource>();
#Column(name = "valueReference")
#SerializedName("valueReference")
#Expose
private String valueReference;
#Column(name = "uuid")
#SerializedName("uuid")
#Expose
private String uuid;
#Column(name = "display")
#SerializedName("display")
#Expose
private String display;
#Column(name = "links")
#SerializedName("links")
#Expose
private List<Link> links = new ArrayList<Link>();
public FormResource()
{
super();
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public List<Link> getLinks() {
return links;
}
public void setLinks(List<Link> links) {
this.links = links;
}
public String getValueReference() {
return valueReference;
}
public void setValueReference(String valueReference) {
this.valueReference = valueReference;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<FormResource> getResources() {
return resources;
}
public void setResources(List<FormResource> resources) {
this.resources = resources;
}
}
Now, I obtain the Formresources once while starting the application and save it. Then in another activity I use the saved formresources to populate a listview. This much works fine. Now, I want to access the nested formresources like this:
formresourcelist.get(position).getResources();
This always returns a blank list of List<FormResource> . What should I do to properly save and retrieve this list? I need to maintain compatibility with Retrofit at the same time.

I think I found a workaround. I made the following changes in the Model Class:
#Table(name = "formresource")
public class FormResource extends Model implements Serializable{
Gson gson=new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Type formresourcelistType = new TypeToken<List<FormResource>>(){}.getType();
#SerializedName("resources")
#Expose
private List<FormResource> resources = new ArrayList<FormResource>();
#Column(name = "resources")
#Expose
private String resourcelist;
public List<FormResource> getResources() {
return resources;
}
public void setResources(List<FormResource> resources) {
this.resources = resources;
}
public void setResourcelist()
{
this.resourcelist=gson.toJson(resources,formresourcelistType);
}
public List<FormResource> getResourceList() {
List<FormResource> resourceList=gson.fromJson(this.resourcelist,formresourcelistType);
return resourceList;
}
}
Basically I am serializing the ArrayList and persisting it as a String in the DB. While saving a FormResource, I do the following:
formresourceObject.setResourcelist();
formresourceObject.save();

Since you're using Retrofit to populate the FormResource data, you should not initialize any fields inside the model.
This line is the problem :
private List<FormResource> resources = new ArrayList<FormResource>();
try removing the initialization and just declare the field like :
private List<FormResource> resources;
and then try calling formresourcelist.get(position).getResources();
Good luck!

Related

DynamoDB/Jackson removing 'is' prefix from property name of the entity [duplicate]

I have a dynamodb table named opx_user_profiles. The entity is shown below, however the attribute user_profile_id is getting saved as userProfileID in the table, even though the #DynamoDBAttribute(attributeName = USER_PROFILE_ID) is specified on the attribute. Other attributes like date_created are getting saved as expected.
I have read the documentation but still not able to find the root cause of the issue. Is it is a bug in dynamo DB?
#DynamoDBTable(tableName = "opx_user_profiles")
public class UserProfileEntity implements Serializable
{
public static final String USER_PROFILE_ID="user_profile_id";
public static final String DATE_CREATED = "date_created";
public static final String EXPIRY_DATE = "expiry_date";
public static final String USERNAME ="username";
public static final String CONTACT_NAME ="contact_name";
private static final long serialVersionUID = 1L;
#DynamoDBAttribute(attributeName = USER_PROFILE_ID)
private Integer userProfileId;
#DynamoDBAttribute(attributeName = USERNAME)
private String userName;
#DynamoDBAttribute(attributeName = CONTACT_NAME)
private String contactName;
#DynamoDBAttribute(attributeName = DATE_CREATED)
private Date dateCreated;
#DynamoDBAttribute(attributeName = EXPIRY_DATE)
private long expiryDate;
public Integer getUserProfileID()
{
return userProfileId;
}
public void setUserProfileID(Integer userProfileId)
{
this.userProfileId = userProfileId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getContactName()
{
return contactName;
}
public void setContactName(String contactName)
{
this.contactName = contactName;
}
public Date getDateCreated()
{
return dateCreated;
}
public void setDateCreated(Date dateCreated)
{
this.dateCreated = dateCreated;
}
}
Even though the official AWS documentation says we may apply the annotation #DynamoDBAttribute class field, I could not make it work like this. However, as seen in this AWS example, I could apply without any problem the annotation to the getter methods.
Please try the following:
#DynamoDBTable(tableName = "opx_user_profiles")
public class UserProfileEntity implements Serializable
{
public static final String USER_PROFILE_ID="user_profile_id";
...
private Integer userProfileId;
...
#DynamoDBAttribute(attributeName = USER_PROFILE_ID)
public Integer getUserProfileID()
{
return userProfileId;
}
public void setUserProfileID(Integer userProfileId)
{
this.userProfileId = userProfileId;
}
...
}
One more option.
If you want to reduce code boilerplates you might use Lombok's #Getter this way:
#Getter(onMethod = #__({#DynamoDbAttribute("address")}))
private String address;
p.s.: It won't impact performance cause the code generation happens not in runtime but the entity looks better IMO.

How to store non-primitive datatype in Room persistence library?

I am unable to add a non-primitive datatype (Book) in Room DB.
Some people suggested to use TypeConverter but i am not being able to use it for my use case.
The following is my entity class:-
#Entity(tableName = "download_table")
public class BookDownload {
#PrimaryKey(autoGenerate = true)
private int id;
private Book bookData;
public BookDownload(String user, Book book) {
bookData = book;
}
public void setId(int id) {
this.id = id;
}
public Book getBookData() {
return bookData;
}
}
I get this error at compile time
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private Book bookData;
^
This is my Book.java class:-
public class Book extends BookItem {
private String publisher;
private String publishedDate;
private String description;
private int pageCount;
private String category;
private double rating;
private int no_ratings;
private String lang;
private String webReaderLink;
private String downloadLink;
public Book(BookItem bookItem) {
super(bookItem.getBookId(), bookItem.getTitle(), bookItem.getAuthor(), bookItem.getImage());
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
//More getters and setters....
}

Retrofit get List can't be worked into a String

While producing a list of my Entity I can't convert this to a String.
This is my Team code:
public class Teams {
#SerializedName("teamName")
#Expose
private String teamName;
#SerializedName("matches")
#Expose
private Object matches;
#SerializedName("players")
#Expose
private Object players;
#SerializedName("id")
#Expose
private Integer id;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Object getMatches() {
return matches;
}
public void setMatches(Object matches) {
this.matches = matches;
}
public Object getPlayers() {
return players;
}
public void setPlayers(Object players) {
this.players = players;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
I'm using the following get:
public interface SoccerStatsApi {
String jsonUrl = "https://soccerstatsapp.azurewebsites.net/api/";
#GET("teams")
Call<List<Teams>> getTeams();`
And this is where I want to convert it to a complete string:
Call<List<Teams>> call = soccerStatsApi.getTeams();
call.enqueue(new Callback<List<Teams>>() {
#Override
public void onResponse(Call<List<Teams>> call, Response<List<Teams>> response) { }
Response().body().toString() only returns the initial string, not the actual object values in the List/response. I've checked everywhere, but so far no answer I can actually work with.
cast Response.body() to List.
for example:
'''List teams = (List)response.body() ;'''
hope you have configured retrofit to use Gson as default json parser

error: Cannot figure out how to save this field into database in my model class

I am developing a new application but I am getting the following error in my code:
Cannot figure out how to save this field into database. You can
consider adding a type converter for it.
I have tried all possible solutions from stackoverflow but did not work.
below my Article.java model class
#Entity(
tableName = "article",
foreignKeys = #ForeignKey(
entity = Source.class,
parentColumns = "id",
childColumns = "source"
))
public class Article {
#PrimaryKey
#SerializedName("source")
#NonNull
#Expose
#ColumnInfo(name ="source")
private Source source;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
#SerializedName("author")
#Expose
#ColumnInfo(name = "author")
private String author;
#SerializedName("title")
#Expose
#ColumnInfo(name = "title")
private String title;
#SerializedName("description")
#Expose
#ColumnInfo(name = "description")
private String description;
#SerializedName("url")
#Expose
#ColumnInfo(name = "url")
private String url;
#SerializedName("urlToImage")
#Expose
#ColumnInfo(name = "urlToImage")
private String urlToImage;
#SerializedName("publishedAt")
#Expose
#ColumnInfo(name = "publishedAt")
private String publishedAt;
#SerializedName("content")
#Expose
#ColumnInfo(name = "content")
private String content;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
below Source.java
below Dao class
#Dao
public interface SportNewsDao {
#Query("SELECT * FROM article")
List<Article> getArticles();
#Insert
void insertAll(Article... article);
#Delete
void delete(Article article);
#Update
void update(Article article);
}
below Database class
#Database(entities = {Article.class,Source.class}, version = 1, exportSchema = false)
public abstract class SportNewsDatabase extends RoomDatabase {
public abstract SportNewsDao sportNewsDao();
}
below SourceTypeConverter.java
public class SourceTypeConverter {
#TypeConverter
public static Source ConvertSource(Source source){
return source == null ? null : new Source(source);
}
}
In order to use your SourceTypeCoverter you need to add the following annotation to your SportNewsDatabase class
#TypeConverters(SourceTypeConverter.class)
Also, your SourceTypeConverter may be missing a method. You need a method to convert your Object to some form of primitive and then from the primitive back to your Object. Something like this
public class SourceTypeConverter {
#TypeConverter
public static String ConvertSource(Source source){
return source == null ? null : source.toString();
}
#TypeConverter
public static Source ConvertSource(String source){
return source == null ? null : new Source(source);
}
}
You can read more about this here, Referencing Complex data using room
Keep in mind using toString() will most likely not work for this. you may need to use something like Gson to convert your object to a string and back.
If that doesn't work, you can always try #embedded. Android Room Embedded
For Room to find SourceTypeConverter you have to register it by annotating your database, Dao or entity with:
#TypeConverters(SourceTypeConverter.class)

I'm passing a list of JSON file is not getting display in the Android application

I was Passing a this JSON http://www.mocky.io/v2/5cacde192f000078003a93bb
i was trying to print a just a category_name
I'm not able to get the data list , when i pass the object with out the data list just like http://www.mocky.io/v2/5cb859344c0000092ed3d4df
private Category_name category_name;
public Category_name getCategoryName() {
return category_name;
}
}
public class Category_name {
#SerializedName("category_name")
public String name;
public String getName() {
return name;
}
}````
i can access that through the NewAdapter.java
with the following code
#Override
public void onBindViewHolder(NewsViewHolder holder, int position) {
Log.e("Its coming","NewAdapter");
ApiObject apiObject = apiObjectList.get(position);
holder.title.setText(apiObject.getCategoryName().getName());
}
with the same code I'm not able to get the data list
#SerializedName("data")
public List<Data> data;
public List<Data> getData() {
return data;
}
public class Data {
#SerializedName("details")
private Category_name category_name;
public Category_name getCategoryName() {
return category_name;
}
}
public class Category_name {
#SerializedName("category_name")
public String name;
public String getName() {
return name;
}
}
#Override
public void onBindViewHolder(NewsViewHolder holder, int position) {
Log.e("Its coming","NewAdapter");
ApiObject apiObject = apiObjectList.get(position);
holder.title.setText(apiObject.getData().getCategoryName().getName());
}
I'm not able to access the getCategoryName();
Please help thanks in advance
use json 2 pojo conversion to create proper model class of json data
http://www.jsonschema2pojo.org/
pass whole example object to adapter constructer.
I think you need to follow these way of POJO parsing according to your JSON response.
public class Data{
#Serialization("status")
#Expose
private String status;
#Serialization("data")
#Expose
private List<MyData> data;
Then
public class MyData{
#Serialization("details")
#Expose
private List<Details> getDetails();
#Serialization("product_count")
#Expose
private String Product_count;
#Serialization("products")
#Expose
private List<Products> getProducts();
//setter and getters
}
Details POJO
Public class Details{
#Serialization("category_id")
#Expose
private String category_id;
#Serialization("category_name")
#Expose
private String category_name;
#Serialization("category_icon")
#Expose
private String category_icon;
//setter and getters
}
Products POJO
Public class Products{
#Serialization("product_id")
#Expose
private String product_id;
#Serialization("product_name")
#Expose
private String product_name;
#Serialization("product_image")
#Expose
private String product_icon;
etc
//setter and getters
}

Categories

Resources