user8206380
user8206380

Reputation:

Getting error 'value' is not a valid managed object while implemting Realm in Android App

In my app, I have to fetch JSON data from rest API. I am using Realm as a local database inside the app. Now after creating model classes, I have one controller class where I performed deserialization and stored functionality into Realm DB. But unfortunately, the app is crashing whenever I click the option to see the news page. I have explained in code.

NewsRealmModel Class

public class NewsRealmModel extends RealmObject {
    public static final String ID = "id";
    private String _id;
    private String body;
    private String title;
    private String updatedDate;
    private RealmList<AppImage> appImages;
    private String updatedAt;
    private TeaserImageSmall teaserImageSmall;
    public NewsRealmModel() {
    }

    public static String getID() {
        return ID;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }

    public String getBody() {
        return body;
    }

    public void setUpdatedDate(String updatedDate) {
        this.updatedDate = updatedDate;
    }

    public RealmList<AppImage> getAppImages() {
        return appImages;
    }

    public void setAppImages(RealmList<AppImage> appImages) {
        this.appImages = appImages;
    }

    public String getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(String updatedAt) {
        this.updatedAt = updatedAt;
    }

    public TeaserImageSmall getTeaserImageSmall() {
        return teaserImageSmall;
    }

    //getting error for this.teaserImageSmall = teaserImageSmall;
    public void setTeaserImageSmall(TeaserImageSmall teaserImageSmall) {
        this.teaserImageSmall = teaserImageSmall;
    }

}

TeaserImageSmall Class

public class TeaserImageSmall extends RealmObject{
    private String alt;
    private String src;
    public String getSrc() {
        return src;
    }

    public void setSrc(String src) {
        this.src = src;
    }

}

Now, the AppImage Class

public class AppImage extends RealmObject{
    private String _id;
    private String alt;
    private String src;
    //getter and setter
}

The Controller Class is

public class NewsController {
    private static final String TAG = NewsController.class.getSimpleName();
    private UserCallbackListener mListener;
    private NewsRestApiManager mApiManager;
    private AppImage appImages;
    Realm myNews_realm;
    public NewsController(NewsPage listener) {
        mListener = listener;
        mApiManager = new NewsRestApiManager();
    }

    public void startFetching(){
        myNews_realm = Realm.getDefaultInstance();
        mApiManager.getNewsApi().getNews(new Callback<String>() {
            @Override
            public void success(String s, Response response) {
                Log.d(TAG, "JSON :: " + s);
                try {
                    JSONArray array = new JSONArray(s);
                    for(int i = 0; i < array.length(); i++) {
                        JSONObject jsonObject = array.getJSONObject(i);
                        Log.d("-----Start Fetching---", jsonObject.optString( "title" ));
                        myNews_realm.beginTransaction();
                        NewsRealmModel news = myNews_realm.createObject( NewsRealmModel.class );
                        news.setTitle( jsonObject.optString( "title") );
                        news.setBody( jsonObject.optString( "body" ) );
                        news.setUpdatedAt( jsonObject.getString( "updated_at" ) );
                        ArrayList<AppImage> list = new ArrayList();
                        JSONArray imageArray =jsonObject.getJSONArray("appImages");
                        if (imageArray.length() > 1) {
                            for(int j=0; j<imageArray.length();j++){
                                appImages  = new AppImage();
                                try {
                                    appImages.setSrc( new JSONArray( s ).getJSONObject( i ).getJSONArray( "appImages" ).getJSONObject( j ).optString( "src" ) );
                                }
                                catch (JSONException e){
                                    e.printStackTrace();
                                }
                                list.add(appImages);
                            }
                        }
                        news.setAppImages( list );
                        // I am getting error for this line
                        TeaserImageSmall coverImage=new TeaserImageSmall();
                        coverImage.setSrc( new JSONArray( s ).getJSONObject( i ).getJSONObject( "teaserImageSmall" ).optString( "src" ));
                        news.setTeaserImageSmall(myNews_realm.copyToRealmOrUpdate(coverImage));;
                        //error in this line
                        myNews_realm.commitTransaction();
                    }
                }
                catch (JSONException e) {
                    mListener.onFetchFailed();
                }
                mListener.onFetchComplete();
            }
            @Override
            public void failure(RetrofitError error) {
                Log.d(TAG, "Error :: " + error.getMessage());
                mListener.onFetchComplete();
            }
        });
    }

    public interface UserCallbackListener{
        void onFetchStart();
        void onFetchComplete();
        void onFetchFailed();
    }

}

The Logcat is showing following error

09-02 21:11:43.050 7337-7337/demo.app.com.bluapp_client_and E/AndroidRuntime: FATAL EXCEPTION: main

Process: demo.app.com.bluapp_client_and, PID: 7337
    java.lang.IllegalArgumentException: A RealmObject with no @PrimaryKey cannot be updated: class demo.app.com.bluapp_client_and.RealmModel.TeaserImageSmall
at io.realm.Realm.checkHasPrimaryKey(Realm.java:1615)
        at io.realm.Realm.copyToRealmOrUpdate(Realm.java:1030)
        at demo.app.com.bluapp_client_and.controller.NewsController$1.success(NewsController.java:134)
        at demo.app.com.bluapp_client_and.controller.NewsController$1.success(NewsController.java:99)

Upvotes: 0

Views: 1350

Answers (1)

EpicPandaForce
EpicPandaForce

Reputation: 81588

Your code will not crash anymore with this error if you replace

news.setTeaserImageSmall(coverImage); //error in this line

With

news.setTeaserImageSmall(realm.copyToRealm(coverImage));

Because news is managed object, so coverImage has to be managed object as well.

Upvotes: 3

Related Questions