I am making an app where I am using room as a database cache and fetching data from the server using retrofit2 and saving it in room database but after fetching from server data is unable to insert in room database.
Here is an exception it is showing:
This is my pojo class below:
#Entity(tableName = "Users")
public class User {
#NonNull
#PrimaryKey
#SerializedName("_id")
private String _id;
#ColumnInfo(name = "name")
#SerializedName("name")
#Expose
private String name;
#ColumnInfo(name = "age")
#SerializedName("age")
#Expose
private String age;
public User(){}
public User(#NonNull String _id,String name, String age) {
this._id = _id;
this.name = name;
this.age = age;
}
#NonNull
public String get_id() {
return _id;
}
public void set_id(#NonNull String _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
JSON Response
[
{
"id": "5cf68fe7b439470017236249",
"name": "Rhea",
"age": "2"
},
{
"id": "5d09006696a8470cbc7c34a2",
"name": "Don",
"age": "10"
},
{
"id": "5d092d9858af5d22a80858bf",
"name": "Roman",
"age": "30"
},
{
"id": "5d09e9976f3bad18b8fa54a0",
"name": "Roman",
"age": "30"
},
{
"id": "5d09ea2ac127bd07b4b64f6f",
"name": "Roman",
"age": "30"
}
]
Someone please let me know what is happening wrong. Any hep would be appreciated.
chnage
#NonNull
#PrimaryKey
#SerializedName("_id") // key does not match with response key
private String _id;
to
#NonNull
#PrimaryKey
#SerializedName("id")
private String _id;
It seems that you have the id parameter named as "id" in your JSON while your model is waiting for "_id". Try removing that leading underscore symbol.
I think that one or more users id that you are fetching data from the server using retrofit2 is null, and because of that you can't insert into your local database
Related
Actually I want to use tree Json response for my react native application. So I build that in spring boot. But due to "children": [] in last child I face some issue in react native. So I want to hide that from my response.
1.I got this type of response
[{
"id": 1,
"name": "Martin",
"haveAccount": false,
"gender": "m",
"children": [
{
"id": 4,
"name": "Werite",
"haveAccount": false,
"gender": "f",
"children": []
}
]
}]
2.But I don't want "children": [] in last child
example:-
[{
"id": 1,
"name": "Martin",
"haveAccount": false,
"gender": "m",
"children": [
{
"id": 4,
"name": "Werite",
"haveAccount": false,
"gender": "f"
}
]
}]
3.Here is my Entity class
#Service
#Entity
#Table
public class Family {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY )
#Column(name="Family_id")
private Integer id;
private String name;
private String village;
private String wifeName;
private String talukaName;
private Boolean haveAccount;
private String username;
private String gender;
private String mobileNumber;
#OneToOne
#JoinColumn(name = "parent_id")
#JsonBackReference
private Family parent;
#OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
#JsonManagedReference
private List<Family> children = new ArrayList<>();
public Family(Integer id, String name, String village, String wifeName, String talukaName, Boolean haveAccount,
String username, String gender, String mobileNumber, Family parent, List<Family> children) {
super();
this.id = id;
this.name = name;
this.village = village;
this.wifeName = wifeName;
this.talukaName = talukaName;
this.haveAccount = haveAccount;
this.username = username;
this.gender = gender;
this.mobileNumber = mobileNumber;
this.parent = parent;
this.children = children;
}
public Family() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Family getParent() {
return parent;
}
public void setParent(Family parent) {
this.parent = parent;
}
public List<Family> getChildren() {
return children;
}
public void setChildren(List<Family> children) {
this.children = children;
}
public void addChild(Family children) {
this.children.add(children);
}
public String getVillage() {
return village;
}
public void setVillage(String village) {
this.village = village;
}
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
public String getTalukaName() {
return talukaName;
}
public void setTalukaName(String talukaName) {
this.talukaName = talukaName;
}
public Boolean getHaveAccount() {
return haveAccount;
}
public void setHaveAccount(Boolean haveAccount) {
this.haveAccount = haveAccount;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
If you want to delete a field you can put it a null and use #JsonInclude(Include.NON_NULL) on your class as follow:
#Service
#Entity
#Table
#JsonInclude(Include.NON_NULL)
public class Family {
//class
}
If you can handle that you should substitute private List<Family> children = new ArrayList<>(); with private List<Family> children; and initialize it when you are going to use it.
Just a question: Why are you using #Service on your entity class?
I have model (Hospital) that has a property of of (Procedure). When I first create the Hospital with a POST that's just the name, contact, etc. I then wanted to update the Procedure property in a different PUT request.
I've tried calling the setProcedure setter but when I do I keep getting this in my Procedures property for the Hospital Object,
"procedure": {
"scanAvailable": true,
"prefetch": -1
}
// it should be like so i.e example
"procedure": {
"name": "xray",
"price": 1.0,
"hosp_id": 111..,
"id" : 222...
}
I first create(POST) create the hospital, after I would update(PUT) by pushing or setting the Flux of procedures int the procedure property.
{
"name": "Mercy Hospital",
"address": "3663 S Miami Ave",
"phone": "305-854-4400",
"zipcode": "33133",
"city": "Miami",
"state": "FL",
"lat": 25.7400049,
"lng": -80.21352600000002,
"procedure": {
"scanAvailable": true, <---- the response i'm getting
"prefetch": -1
},
"id": "5d539346e440ed05dfd0fe8a"
}
Like I mentioned I created two models with a constructor and getters and setters for each.
Hospital
#Document // Identifies this class as domain object to be persisted to mongodb
public class Hospital {
private String name;
private String address;
private String phone;
private String zipcode;
private String city;
private String state;
private double lat;
private double lng;
private List<Procedure> procedure;
#Id
private String id;
//
public Hospital() {
}
public Hospital(String name, String address, String phone, String zipcode, String city, String state, double lat, double lng) throws InterruptedException, ApiException, IOException {
this.name = name;
this.phone = phone;
this.address = address;
this.city = city;
this.state = state;
this.zipcode = zipcode;
this.lat = lng;
this.lng = lng;
}
// All the Getters and Setters
Procedure
#Document
public class Procedure {
private String name;
private double price;
private String hosp_id;
#Id
private String id;
public Procedure() {
}
public Procedure(String name, double price, String hosp_id) {
this.name = name;
this.price = price;
this.hosp_id = hosp_id;
}
// all the Getters and setters Here
}
Controller :
#RestController // Controller and ResponseBody Annotations together
#RequestMapping("/hospitals/v1/hosp/") // Create a base string that the endpoint is built upon
#CrossOrigin // For DEV Angular and Spring app locally REMOVE FOR PRODUCTION
public class HospitalController {
private final HospitalService hospitalService;
#Autowired
public HospitalController(HospitalService hospitalService) {
this.hospitalService = hospitalService;
}
#GetMapping(path = "{id}", produces =
MediaType.APPLICATION_JSON_UTF8_VALUE)
public Mono<Hospital> getHospital(#PathVariable String id) {
return hospitalService.getHospital(id);
}
#PutMapping(path = "{hosp_id}/services", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Mono<Hospital> createService(#RequestBody List<Procedure> procedureMono, #PathVariable String hosp_id) {
return hospitalService.createService(procedureMono, hosp_id);
}
Service
public Mono<Hospital> getHospital(String id) {
return reactiveMongoOperations.findById(id, Hospital.class);
}
public Mono<Hospital> createService(List<Procedure> procedureMono, String hosp_id) {
return getHospital(hosp_id).doOnNext(hospital -> hospital.setProcedure(procedureMono));
}
You get this because you are trying to serialize/deserialize a Flux or a Mono.
you can't return a
public class Hospital {
private Flux<Procedure> procedure;
}
You can only serialize/deserialize concrete types
public class Hospital {
private List<Procedure> procedure;
}
Since you have not posted your full controller i can not understand fully what it is you want to do, but you can't serialize/deserialize Monos or Fluxes.
I have a file called persons.json:
[
{
"id": 1,
"name": "The Best",
"email": "thenextbigthing#gmail.com",
"birthDate": "1981-11-23"
},
{
"id": 2,
"name": "Andy Jr.",
"email": "usa#gmail.com",
"birthDate": "1982-12-01"
},
{
"id": 3,
"name": "JohnDoe",
"email": "gameover#gmail.com",
"birthDate": "1990-01-02"
},
{
"id": 4,
"name": "SomeOne",
"email": "rucksack#gmail.com",
"birthDate": "1988-01-22"
},
{
"id": 5,
"name": "Mr. Mxyzptlk",
"email": "bigman#hotmail.com",
"birthDate": "1977-08-12"
}
]
I'd like to parse this file into an ArrayList with FasterXML, possibly with it's ObjectMapper() function and then being able to access each value (id, name, etc.) individually as a String when iterating through the newly created ArrayList. How could I do that? I don't even know what kind of list I could/should use in order to get access to each value individually. I'm kind of stuck here. List<???>
First of all:
FasterXML uses Jackson underneath to parse/produce json.
Now: to use Jackson, first of all create a container object for the data of your json, which we will call Person
public class Person {
private int id;
private String name, email;
#JsonFormat
(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date birthDate;
//add here getters and setters ...
}
At this point, supposing you have pathToPersonsJsonFile as a string containing the path to your persons.json, you can use your file like this:
byte[] jsonData = Files.readAllBytes(Paths.get(pathToPersonsJsonFile));
ObjectMapper objectMapper = new ObjectMapper();
Person[] parsedAsArray = objectMapper.readValue(jsonData, Person[].class); //array
ArrayList<Persons> persons = new ArrayList<>(Arrays.asList(parsedAsArray)); //your list
Note: JsonFormat enables to declare which format that value has on your json.
First you should create POJO for storing info:
public class Person {
Long id;
String name;
String email;
#JsonFormat("yyyy-mm-dd")
Date birthDate;
...
}
next you should call:
List<Person> myObjects = new ObjectMapper().readValue(jsonInput, new TypeReference<List<Person>>(){});
This should be enough
ObjectMapper objectMapper = new ObjectMapper();
List<Person> list = objectMapper.readValue(new File("path_to_persons.json"), new TypeReference<List<Person>>(){});
public class Person {
private String id;
private String name;
private String email;
private String birthDate;
.....
}
1) First create class Person.java
2) Then read the persons.json file and create a JSONArray from it.
3) Then parse as given below:
class Person{
private int id;
private String name;
private String email;
private String birthDate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getBirthDate() {
return birthDate;
}
public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}
}
public List<Person> getPersonList(JSONArray dataArray){
List<Person> personList = new ArrayList<>();
for(int i=0; i<dataArray.length(); i++){
try {
JSONObject personJsonObject = dataArray.getJSONObject(i);
Person person = new Person();
if(personJsonObject.has("id") && !personJsonObject.isNull("id")){
person.setId(personJsonObject.getInt("id"));
}
if(personJsonObject.has("name") && !personJsonObject.isNull("name")){
person.setName(personJsonObject.getString("name"));
}
if(personJsonObject.has("email") && !personJsonObject.isNull("email")){
person.setEmail(personJsonObject.getString("email"));
}
if(personJsonObject.has("birthDate") && !personJsonObject.isNull("birthDate")){
person.setBirthDate(personJsonObject.getString("birthDate"));
}
personList.add(person);
}catch (JSONException e){
}
}
return personList;
}
4) Then use this list wherever you want.
Hi there i have this JSON i´m mapping the "Users" with gson but i need to consolidate the maps (in this example 2 but can be more) in only 1 Map or 1 List be cause i need to send the consolidate to a Custom Adapter, as you can see i had 2 list of users and i access to each list users and atributes without problem but i need to create just 1 map or list, is there anyway to consolidate that mutivalue maps in only one?
[{
"id": 999098,
"name": "Legendary Users",
"users": {
"98087ffg5": {
"Age": 20,
"name": "dighak"
},
"0987499gg8": {
"Age": 18,
"name": "kijhg"
},
"1231ghty56": {
"Age": 19,
"name": "ramn1"
}
}
},
{
"id": 999098,
"name": "Best Users",
"users": {
"12312bvf123": {
"Age": 20,
"name": "thispa"
},
"50827gh65": {
"Age": 21,
"name": "vista1"
}
}
}]
This is my Response.class
public class Response {
private int id;
private String name;
private Map<String,UsersBean> users = new LinkedHashMap<>();
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Map<String,UsersBean> getUsers() {return users;}
public void setUsers(Map<String,UsersBean> users) {this.users = users;}
public static class UsersBean {
private int Age;
private String name;
public int getAge() {return Age;}
public void setAge(int Age) {this.Age = Age;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
}
I can access to each list of users like this
Response response;
response.get(0).getUsers().get("98087ffg5").getAge();
but i need an consolidate data of list of users with all the keys and respective values, can you help my with this? i need to create a new class o map and use for loop? for access to all like:
list/map.getUsers().get("98087ffg5").getAge();
Why not use an array or arrayList of your Response class?
For example, setting the JSON string:
String jsonString = new Gson().toJson(responseArray);
...and getting the array of responses from it:
Response[] responseArray = new Gson().fromJson(jsonString, Response[].class);
Hi i'm trying to learn android and now implementing the retrofit 1.9 for my rest POST and GET request can somebody help me on how to model given json objects and strings? im very confused on some tutorials I have learned how make a pojo for this json object
{
"contacts": [
{
"id": "c200",
"name": "Ravi Tamada",
"email": "ravi#gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
{
"id": "c201",
"name": "Johnny Depp",
"email": "johnny_depp#gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
}
}}]}
Using this model
Contacts.class
public class Contacts {
#SerializedName("contacts")
#Expose
private List<Contact> contacts = new ArrayList<Contact>();
public List<Contact> getContacts() {
return contacts;
}
public void setContacts(List<Contact> contacts) {
this.contacts = contacts;
}
and Contact.class for the objects
public class Contact {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("email")
#Expose
private String email;
#SerializedName("address")
#Expose
private String address;
#SerializedName("gender")
#Expose
private String gender;
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getEmail() {return email;}
public void setEmail(String email) {this.email = email;}
public String getAddress() {return address;}
public void setAddress(String address) {this.address = address;}
public String getGender() {return gender;}
public void setGender(String gender) {this.gender = gender;}}
And Calling the list using this on my MainActivity.class
private void getContacts() {
final ProgressDialog loading = ProgressDialog.show(this, "Fetching Data", "Please wait...", false, false);
RestAdapter adapter = new RestAdapter.Builder().setEndpoint(ROOT_URL).build();
ContactsAPI api = adapter.create(ContactsAPI.class);
api.getContacts(new Callback<Contacts>() {
#Override
public void success(Contacts contacts, Response response) {
loading.dismiss();
List<Contact> contactList = contacts.getContacts();
String[] items = new String[contactList.size()];
for (int i = 0; i < contactList.size(); i++) {
items[i] = contactList.get(i).getName();
}
ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.simple_list,R.id.textview, items);
//Setting adapter to listviesw
listView.setAdapter(adapter);
}
#Override
public void failure(RetrofitError error) {
}
});
}
THen my Question is how should i make a model out of this array Object?
{
"-KNea90tV5nZlkeqxc3Q": {
"accountName": "Mark Papyrus",
"accountNumber": "12435656443",
"accountType": "Peso Savings"
},
"-KNeaPmBoTXV4mQC6cia": {
"accountName": "Mark Dremeur",
"accountNumber": "12435656444",
"accountType": "Peso Checking"
}
i found it confusing how to make models and difference of given json arrays pls guide me thanks.
I think me and you are having the same problems but I am stuck so I can help you as far as I can . First you cannot use jsonschema2pojo.org to create the pojo class you need to use hashmap from what I understand "-KNea90tV5nZlkeqxc3Q": is a key but 1 of the classes should be the following ( also the accountype since its a type you can use enum but it would be bit harder to code)
public class Account {
private String accountName;
private String accountNumber;
private String accountType;
public Account() {
}
public String getAccountName() {return accountName;}
public void setAccountName(String accountName) {
this.accountName=accountName;}
// *** repeat for the accountnumber and accountype
}
if the key "KNea90tV5nZlkeqxc3Q" is dynamic and need to capture them, you musto to use a hashmap in your model to catch them correctly.
check this issue it could be useful:
Parse Dynamic Key Json String using Retrofit