I'm trying to synchronize my local database with remote data using ActiveAndroid. I have local data stored in entity User
that will be replaced with new data retrieved from JSON.
This is my User class
This is the complete entity
@Table(name = "User")
public class User extends Model {
@Column(name = "user_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
public int user_id;
@SerializedName("username")
@Column(name = "username")
public String username;
@SerializedName("name")
@Column(name = "name")
public String name;
@SerializedName("address")
@Column(name = "address")
public String address;
@SerializedName("bio")
@Column(name = "bio")
public String bio;
@SerializedName("gender")
@Column(name = "gender")
public String gender;
@SerializedName("avatar")
@Column(name = "avatar")
public String avatar;
}
And this is JSON result returned from API
{
user: {
username: "ahmeds",
name: "ahmed shalih",
address: "California",
bio: "IOS Developer",
gender: "M",
avatar: "http://myserverapi/avatar/2728/mdvhnzcyyzmtmd.jpeg",
id: 2728,
}
}
I tried to parse the json above using Gson and save it into database. But actually this user data has been already stored in local database. So, I just want to make it updated.
try{
JSONObject json = new JSONObject(returnedJSON);
JSONObject jsonUser = json.optJSONObject("user");
Gson gson = new Gson();
User updatedUser = gson.from(jsonUser.toString(), User.class);
updatedUser.save(); //add or update the local data
}catch(JSONException ex){
ex.printStackTrace();
}
The problem is when I tried to save it, I got error message like this
Error Inserting
android.database.sqlite.SQLiteConstraintException: foreign key constraint failed (code 19)
I then understand that this error happened because I defined user_id
with unique attribute which means that it prevent duplicate row with same user_id
.
I've read the documentation about update mechanism in ActiveAndroid and I've tried it like this.
User existingUser = new Select().from(User.class).where("user_id = ?", jsonUser.optInt("user_id").executeSingle();
if(existingUser != null){
Gson gson = new Gson();
User updatedUser = gson.from(jsonUser.toString(), User.class);
existingUser.name = updatedUser.name;
existingUser.adress = updatedUser.name;
existingUser.gender = updatedUser.gender;
existingUser.bio = updatedUser.bio.
existingUser.avatar = updatedUser.avatar;
//...rest of code
// Oh,.. I've to update it all
existingUser.save(); //update
}else{
//insert new
Gson gson = new Gson();
User updatedUser = gson.from(jsonUser.toString(), User.class);
updatedUser.save();
}
This last solution is actually work. But we can see above that if we have many columns (attributes) in User table, then we have to individually update the attributes to perform synchronisation.
Any solution to make it simple?