realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.74k forks source link

Count returning wrong value. #1799

Closed gintechsystems closed 8 years ago

gintechsystems commented 8 years ago

I have the following code and have tested throughly, the count should be returning 3 but only returns 1. I have checked how many items I have before parsing with GSON and after. They always return 3. I have checked to make sure propertyFollowed is 1 and not 0, they all say 1. Why is this returning the wrong value?

            List<PropertyObject> favsList = new ArrayList<>();
            for (int i = 0; i < favorites.size(); i++) {
                PropertyObject fav = visnetawrap.gsonClient.fromJson(favorites.get(i).toString(), PropertyObject.class);
                favsList.add(fav);
            }
            realmThread.beginTransaction();
            realmThread.copyToRealmOrUpdate(favsList);
            realmThread.commitTransaction();

            for (int i = 0; i < favsList.size(); i++) {
                PropertyObject fav = favsList.get(i);
                Log.d("PropFollowed", String.valueOf(fav.getPropertyFollowed()));
            }

final long favoritesCount = realmThread.where(PropertyObject.class).equalTo("propertyFollowed", 1).count();
zaki50 commented 8 years ago

Hi @gintechsystems

Can you provide definition of PropertyObject and json strings? And what version of Realm are you using?

gintechsystems commented 8 years ago

Sure thing. I am using Realm version 0.84.1.

Here is the code for PropertyObject followed by the JSON string.

public class PropertyObject extends RealmObject {
    @PrimaryKey
    @SerializedName("id")
    private String propertyId;

    @SerializedName("customer_case")
    private String propertyCustomerCase;

    @SerializedName("status")
    private String propertyStatus;
    @SerializedName("step")
    private String propertyStep;

    @SerializedName("loan")
    private String propertyLoan;

    @SerializedName("circle_id")
    private String propertyCircleId;
    @SerializedName("circle_name")
    private String propertyCircleName;

    @SerializedName("latitude")
    private Double propertyLat;
    @SerializedName("longitude")
    private Double propertyLng;

    @SerializedName("address")
    private String propertyAddress;
    @SerializedName("city")
    private String propertyCity;
    @SerializedName("county")
    private String propertyCounty;
    @SerializedName("state")
    private String propertyState;

    @SerializedName("google_address")
    private String propertyGoogleAddress;
    @SerializedName("google_city")
    private String propertyGoogleCity;
    @SerializedName("google_county")
    private String propertyGoogleCounty;
    @SerializedName("google_state")
    private String propertyGoogleState;

    @SerializedName("verified_zip")
    private String propertyVerifiedZip;
    @SerializedName("zip")
    private String propertyZip;

    @SerializedName("marketing_front")
    private String propertyMarketFrontPic;
    @SerializedName("profile_picture")
    private String propertyProfilePic;
    @SerializedName("street_view")
    private String propertyStreetViewPic;

    @SerializedName("property_type")
    private String propertyType = "";
    @SerializedName("description")
    private String propertyDescription;

    @SerializedName("followed")
    private long propertyFollowed;

    @SerializedName("list_price")
    private String propertyPrice;

    @SerializedName("built")
    private String propertyBuilt;

    @SerializedName("bathroom")
    private Double propertyBathrooms;
    @SerializedName("bedroom")
    private Double propertyBedrooms;

    @SerializedName("sqft")
    private String propertySquareFeet;
    @SerializedName("lot_size")
    private String propertyLotSize;

    @SerializedName("winterized")
    private String propertyWinterized;
    @SerializedName("sump_pump")
    private String sumpPump;

    @SerializedName("gate_code")
    private String gateCode;
    @SerializedName("key_code")
    private String keyCode;
    @SerializedName("lockbox")
    private String lockBox;

    @SerializedName("client_id")
    private String clientCompanyId;
    @SerializedName("client")
    private String clientCompany;
    @SerializedName("client_email")
    private String clientEmail;
    @SerializedName("client_phone")
    private String clientPhone;

    @SerializedName("fsm_company_id")
    private String fsmCompanyId;
    @SerializedName("fsm_company")
    private String fsmCompany;
    @SerializedName("fsm_email")
    private String fsmEmail;
    @SerializedName("fsm_phone")
    private String fsmPhone;

    @SerializedName("hoa_id")
    private String hoaCompanyId;
    @SerializedName("hoa")
    private String hoaCompany;
    @SerializedName("hoa_email")
    private String hoaEmail;
    @SerializedName("hoa_phone")
    private String hoaPhone;

    @SerializedName("broker_id")
    private String brokerCompanyId;
    @SerializedName("broker")
    private String brokerCompany;
    @SerializedName("broker_email")
    private String brokerEmail;
    @SerializedName("broker_phone")
    private String brokerPhone;

    @SerializedName("police_id")
    private String policeCompanyId;
    @SerializedName("police")
    private String policeCompany;
    @SerializedName("police_phone")
    private String policePhone;

    @SerializedName("water_id")
    private String waterCompanyId;
    @SerializedName("water")
    private String waterCompany;
    @SerializedName("water_phone")
    private String waterPhone;

    @SerializedName("sewer_id")
    private String sewerCompanyId;
    @SerializedName("sewer")
    private String sewerCompany;
    @SerializedName("sewer_phone")
    private String sewerPhone;

    @SerializedName("electric_id")
    private String electricCompanyId;
    @SerializedName("electric")
    private String electricCompany;
    @SerializedName("electric_phone")
    private String electricPhone;

    @SerializedName("add_date")
    private Date createdDate;
    @SerializedName("assign_date")
    private Date assignDate;

    public String getPropertyId() {
        return propertyId;
    }

    public void setPropertyId(String propertyId) {
        this.propertyId = propertyId;
    }

    public String getPropertyCustomerCase() {
        return propertyCustomerCase;
    }

    public void setPropertyCustomerCase(String propertyCustomerCase) {
        this.propertyCustomerCase = propertyCustomerCase;
    }

    public String getPropertyStatus() {
        return propertyStatus;
    }

    public void setPropertyStatus(String propertyStatus) {
        this.propertyStatus = propertyStatus;
    }

    public String getPropertyStep() {
        return propertyStep;
    }

    public void setPropertyStep(String propertyStep) {
        this.propertyStep = propertyStep;
    }

    public String getPropertyLoan() {
        return propertyLoan;
    }

    public void setPropertyLoan(String propertyLoan) {
        this.propertyLoan = propertyLoan;
    }

    public String getPropertyCircleId() {
        return propertyCircleId;
    }

    public void setPropertyCircleId(String propertyCircleId) {
        this.propertyCircleId = propertyCircleId;
    }

    public String getPropertyCircleName() {
        return propertyCircleName;
    }

    public void setPropertyCircleName(String propertyCircleName) {
        this.propertyCircleName = propertyCircleName;
    }

    public Double getPropertyLat() {
        return propertyLat;
    }

    public void setPropertyLat(Double lat) {
        this.propertyLat = lat;
    }

    public Double getPropertyLng() {
        return propertyLng;
    }

    public void setPropertyLng(Double lng) {
        this.propertyLng = lng;
    }

    public String getPropertyAddress() {
        return propertyAddress;
    }

    public void setPropertyAddress(String propertyAddress) {
        this.propertyAddress = propertyAddress;
    }

    public String getPropertyCity() {
        return propertyCity;
    }

    public void setPropertyCity(String propertyCity) {
        this.propertyCity = propertyCity;
    }

    public String getPropertyCounty() {
        return propertyCounty;
    }

    public void setPropertyCounty(String propertyCounty) {
        this.propertyCounty = propertyCounty;
    }

    public String getPropertyState() {
        return propertyState;
    }

    public void setPropertyState(String propertyState) {
        this.propertyState = propertyState;
    }

    public String getPropertyGoogleAddress() {
        return propertyGoogleAddress;
    }

    public void setPropertyGoogleAddress(String propertyGoogleAddress) {
        this.propertyGoogleAddress = propertyGoogleAddress;
    }

    public String getPropertyGoogleCity() {
        return propertyGoogleCity;
    }

    public void setPropertyGoogleCity(String propertyGoogleCity) {
        this.propertyGoogleCity = propertyGoogleCity;
    }

    public String getPropertyGoogleCounty() {
        return propertyGoogleCounty;
    }

    public void setPropertyGoogleCounty(String propertyGoogleCounty) {
        this.propertyGoogleCounty = propertyGoogleCounty;
    }

    public String getPropertyGoogleState() {
        return propertyGoogleState;
    }

    public void setPropertyGoogleState(String propertyGoogleState) {
        this.propertyGoogleState = propertyGoogleState;
    }

    public String getPropertyVerifiedZip() {
        return propertyVerifiedZip;
    }

    public void setPropertyVerifiedZip(String propertyVerifiedZip) {
        this.propertyVerifiedZip = propertyVerifiedZip;
    }

    public String getPropertyZip() {
        return  propertyZip;
    }

    public void setPropertyZip(String propertyZip) {
        this.propertyZip = propertyZip;
    }

    public String getPropertyMarketFrontPic() {
        return propertyMarketFrontPic;
    }

    public void setPropertyMarketFrontPic(String propertyMarketFrontPic) {
        this.propertyMarketFrontPic = propertyMarketFrontPic;
    }

    public String getPropertyProfilePic() {
        return propertyProfilePic;
    }

    public void setPropertyProfilePic(String propertyProfilePic) {
        this.propertyProfilePic = propertyProfilePic;
    }

    public String getPropertyStreetViewPic() {
        return propertyStreetViewPic;
    }

    public void setPropertyStreetViewPic(String propertyStreetViewPic) {
        this.propertyStreetViewPic = propertyStreetViewPic;
    }

    public String getPropertyType() {
        return propertyType;
    }

    public void setPropertyType(String propertyType) {
        this.propertyType = propertyType;
    }

    public String getPropertyDescription() {
        return propertyDescription;
    }

    public void setPropertyDescription(String propertyDescription) {
        this.propertyDescription = propertyDescription;
    }

    public long getPropertyFollowed() {
        return propertyFollowed;
    }

    public void setPropertyFollowed(long propertyFollowed) {
        this.propertyFollowed = propertyFollowed;
    }

    public String getPropertyPrice() {
        return propertyPrice;
    }

    public void setPropertyPrice(String propertyPrice) {
        this.propertyPrice = propertyPrice;
    }

    public String getPropertyBuilt() {
        return propertyBuilt;
    }

    public void setPropertyBuilt(String propertyBuilt) {
        this.propertyBuilt = propertyBuilt;
    }

    public Double getPropertyBathrooms() {
        return propertyBathrooms;
    }

    public void setPropertyBathrooms(Double propertyBathrooms) {
        this.propertyBathrooms = propertyBathrooms;
    }

    public Double getPropertyBedrooms() {
        return propertyBedrooms;
    }

    public void setPropertyBedrooms(Double propertyBedrooms) {
        this.propertyBedrooms = propertyBedrooms;
    }

    public String getPropertySquareFeet() {
        return  propertySquareFeet;
    }

    public void setPropertySquareFeet(String propertySquareFeet) {
        this.propertySquareFeet = propertySquareFeet;
    }

    public String getPropertyLotSize() {
        return propertyLotSize;
    }

    public void setPropertyLotSize(String propertyLotSize) {
        this.propertyLotSize = propertyLotSize;
    }

    public String getPropertyWinterized() {
        return propertyWinterized;
    }

    public void setPropertyWinterized(String propertyWinterized) {
        this.propertyWinterized = propertyWinterized;
    }

    public String getSumpPump() {
        return sumpPump;
    }

    public void setSumpPump(String sumpPump) {
        this.sumpPump = sumpPump;
    }

    public String getGateCode() {
        return gateCode;
    }

    public void setGateCode(String gateCode) {
        this.gateCode = gateCode;
    }

    public String getKeyCode() {
        return keyCode;
    }

    public void setKeyCode(String keyCode) {
        this.keyCode = keyCode;
    }

    public String getLockBox() {
        return lockBox;
    }

    public void setLockBox(String lockBox) {
        this.lockBox = lockBox;
    }

    public String getClientCompanyId() {
        return clientCompanyId;
    }

    public void setClientCompanyId(String clientCompanyId) {
        this.clientCompanyId = clientCompanyId;
    }

    public String getClientCompany() {
        return clientCompany;
    }

    public void setClientCompany(String clientCompany) {
        this.clientCompany = clientCompany;
    }

    public String getClientEmail() {
        return clientEmail;
    }

    public void setClientEmail(String clientEmail) {
        this.clientEmail = clientEmail;
    }

    public String getClientPhone() {
        return clientPhone;
    }

    public void setClientPhone(String clientPhone) {
        this.clientPhone = clientPhone;
    }

    public String getFsmCompanyId() {
        return  fsmCompanyId;
    }

    public void setFsmCompanyId(String fsmCompanyId) {
        this.fsmCompanyId = fsmCompanyId;
    }

    public String getFsmCompany() {
        return fsmCompany;
    }

    public void setFsmCompany(String fsmCompany) {
        this.fsmCompany = fsmCompany;
    }

    public String getFsmEmail() {
        return fsmEmail;
    }

    public void setFsmEmail(String fsmEmail) {
        this.fsmEmail = fsmEmail;
    }

    public String getFsmPhone() {
        return fsmPhone;
    }

    public void setFsmPhone(String fsmPhone) {
        this.fsmPhone = fsmPhone;
    }

    public String getHoaCompanyId() {
        return hoaCompanyId;
    }

    public void setHoaCompanyId(String hoaCompanyId) {
        this.hoaCompanyId = hoaCompanyId;
    }

    public String getHoaCompany() {
        return hoaCompany;
    }

    public void setHoaCompany(String hoaCompany) {
        this.hoaCompany = hoaCompany;
    }

    public String getHoaEmail() {
        return  hoaEmail;
    }

    public void setHoaEmail(String hoaEmail) {
        this.hoaEmail = hoaEmail;
    }

    public String getHoaPhone() {
        return hoaPhone;
    }

    public void setHoaPhone(String hoaPhone) {
        this.hoaPhone = hoaPhone;
    }

    public String getBrokerCompanyId() {
        return brokerCompanyId;
    }

    public void setBrokerCompanyId(String brokerCompanyId) {
        this.brokerCompanyId = brokerCompanyId;
    }

    public String getBrokerCompany() {
        return brokerCompany;
    }

    public void setBrokerCompany(String brokerCompany) {
        this.brokerCompany = brokerCompany;
    }

    public String getBrokerEmail() {
        return brokerEmail;
    }

    public void setBrokerEmail(String brokerEmail) {
        this.brokerEmail = brokerEmail;
    }

    public String getBrokerPhone() {
        return brokerPhone;
    }

    public void setBrokerPhone(String brokerPhone) {
        this.brokerPhone = brokerPhone;
    }

    public String getPoliceCompanyId() {
        return policeCompanyId;
    }

    public void setPoliceCompanyId(String policeCompanyId) {
        this.policeCompanyId = policeCompanyId;
    }

    public String getPoliceCompany() {
        return policeCompany;
    }

    public void setPoliceCompany(String policeCompany) {
        this.policeCompany = policeCompany;
    }

    public String getPolicePhone() {
        return policePhone;
    }

    public void setPolicePhone(String policePhone) {
        this.policePhone = policePhone;
    }

    public String getWaterCompanyId() {
        return waterCompanyId;
    }

    public void setWaterCompanyId(String waterCompanyId) {
        this.waterCompanyId = waterCompanyId;
    }

    public String getWaterCompany() {
        return waterCompany;
    }

    public void setWaterCompany(String waterCompany) {
        this.waterCompany = waterCompany;
    }

    public String getWaterPhone() {
        return waterPhone;
    }

    public void setWaterPhone(String waterPhone) {
        this.waterPhone = waterPhone;
    }

    public String getSewerCompanyId() {
        return sewerCompanyId;
    }

    public void setSewerCompanyId(String sewerCompanyId) {
        this.sewerCompanyId = sewerCompanyId;
    }

    public String getSewerCompany() {
        return sewerCompany;
    }

    public void setSewerCompany(String sewerCompany) {
        this.sewerCompany = sewerCompany;
    }

    public String getSewerPhone() {
        return sewerPhone;
    }

    public void setSewerPhone(String sewerPhone) {
        this.sewerPhone = sewerPhone;
    }

    public String getElectricCompanyId() {
        return electricCompanyId;
    }

    public void setElectricCompanyId(String electricCompanyId) {
        this.electricCompanyId = electricCompanyId;
    }

    public String getElectricCompany() {
        return electricCompany;
    }

    public void setElectricCompany(String electricCompany) {
        this.electricCompany = electricCompany;
    }

    public String getElectricPhone() {
        return electricPhone;
    }

    public void setElectricPhone(String electricPhone) {
        this.electricPhone = electricPhone;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Date getAssignDate() {
        return assignDate;
    }

    public void setAssignDate(Date assignDate) {
        this.assignDate = assignDate;
    }
}
{"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","zip":"19007","county":"Bucks County","apt_no":"","latitude":"40.1012666","longitude":"-74.855304","profile_picture":"uploads/thumbnails/2014/06/07/16/1402165202_3_16_539356ad9134b3.jpg","id":"539356ad9134b3","google_address":"10 Canal Street","google_city":"Bristol","google_state":"Pennsylvania","verified_zip":"19007","google_county":"Bucks County","status":"Active","add_date":"2014-06-07","circle_name":"Test Portfolio","step":"Rental","loan":"","winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins@assero24.com","fsm_phone":"2155868317","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"9","client":"Test Client","client_email":"krishna162@gmail.com","client_phone":"2157830782","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":null,"bathroom":null,"sqft":null,"lot_size":null,"list_price":"538525","built":null,"assign_date":"06/07/2014","lock_box":null,"gate_code":null,"key_code":null,"property_type":"Unknown","description":null,"sub_status":null,"occupancy_status":null,"street_view":"uploads/2015/06/25/4036/0470e4cd-ce9d-4439-8031-6be5101cd09c.JPG","marketing_front":"uploads/2015/06/25/4036/b099a190-f354-454a-8479-bec67bc41988.JPG","followed":"1"}
11-18 22:10:29.355 6342-6494/com.droid.visneta D/PropFav: {"customer_case":"19378","circle_id":"3","address":"1046 VALLEYWAY DR","city":"APOPKA","state":"FL ","zip":"32712","county":"Orange County","apt_no":"","latitude":"28.722077","longitude":"-81.531601","profile_picture":"uploads/2014/11/11/2498/96d277c4-914c-4f59-9d74-f67ebbff4447.jpg","id":"546104793bbad3","google_address":"1046 Valleyway Drive","google_city":"Apopka","google_state":"Florida","verified_zip":"32712","google_county":"Orange County","status":"Active","add_date":"2014-11-10","circle_name":"Test Portfolio","step":"Servicing","loan":"1701236713\r\n","winterized":null,"boiler":null,"sump_pump":"No","septic":null,"police_id":"28060","police":"Apopka Police Department","police_phone":"407-703-1771","electric_id":"28069","electric":"Progress Energy","electric_phone":"(800) 700-8744","sewer_id":"28061","sewer":"City of APOPKA Utility Billing","sewer_phone":"407-703-1727","water_id":"28061","water":"City of APOPKA Utility Billing","water_phone":"407-703-1727","fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins@assero24.com","fsm_phone":"2155868317","hoa_id":"27937","hoa":"OAK HILL RESERVE/ GREYSTONE MANAGEMENT","hoa_email":"","hoa_phone":"407)645-4945\t","client_id":"9","client":"Test Client","client_email":"krishna162@gmail.com","client_phone":"2157830782","broker_contact_id":"0","broker":null,"broker_email":null,"broker_phone":"9088512121","lawn_contractor":"Lees Country Kitchen Remodeling","cleaning_contractor":null,"bedroom":"6","bathroom":"2.5","sqft":"2320","lot_size":"20000","list_price":"221782","built":"2006","assign_date":"11/10/2014","lock_box":"","gate_code":null,"key_code":null,"property_type":"SingleFamily","description":null,"sub_status":"","occupancy_status":"Vacant","street_view":"uploads/thumbnails/2014/11/10/16/1415644501_3_16_546104793bbad3.jpg","marketing_front":null,"followed":"1"}
11-18 22:10:29.357 6342-6494/com.droid.visneta D/PropFav: {"customer_case":"161181110","circle_id":"33","address":"3900  8TH PL","city":"DES MOINES","state":"IA","zip":"50313","county":"POLK","apt_no":"","latitude":"41.631438","longitude":"-93.628748","profile_picture":"uploads/2015/01/03/2898/dc72592f-559d-4039-a569-92c98d2450a8.jpg","id":"54a8226b3b52b33","google_address":"3900 8th Place","google_city":"Des Moines","google_state":"Iowa","verified_zip":"50313","google_county":"Polk County","status":"Inactive","add_date":"2015-01-03","circle_name":"Cityside - HUD Contract Area - 4D","step":"Disposed","loan":null,"winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"26792","fsm_company":"Cityside Management Corp.","fsm_email":"HUDAlerts@assero24.com","fsm_phone":"8668321711","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"25491","client":"U.S. Department of Housing and Urban Development (HUD)","client_email":"leemertins@visneta.com","client_phone":"7773473735","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":"2","bathroom":"2.0","sqft":"1325","lot_size":"6585","list_price":"84958","built":"1910","assign_date":"2015-01-05","lock_box":null,"gate_code":null,"key_code":null,"property_type":"SingleFamily","description":null,"sub_status":"10","occupancy_status":null,"street_view":"uploads/thumbnails/2015/01/03/16/1420305305_3_16_54a8226b3b52b33.jpg","marketing_front":null,"followed":"1"}
zaki50 commented 8 years ago

Thanks @gintechsystems I'll look into.

gintechsystems commented 8 years ago

No problem, thank you.

zaki50 commented 8 years ago
List<PropertyObject> favsList = new ArrayList<>();
for (int i = 0; i < favorites.size(); i++) {
    PropertyObject fav = visnetawrap.gsonClient.fromJson(favorites.get(i).toString(), PropertyObject.class);
    favsList.add(fav);
}
realmThread.beginTransaction();
favsList = realmThread.copyToRealmOrUpdate(favsList); // change this line
realmThread.commitTransaction();

for (int i = 0; i < favsList.size(); i++) {
    PropertyObject fav = favsList.get(i);
    Log.d("PropFollowed", String.valueOf(fav.getPropertyFollowed()));
}

final long favoritesCount = realmThread.where(PropertyObject.class).equalTo("propertyFollowed", 1).count();

Can you try above code? And any difference in the log? Your original code does not check the saved value.

gintechsystems commented 8 years ago

I have tried that earlier and it returned 1 for propertyFollowed. I can try again if you like.

gintechsystems commented 8 years ago

I have also tried changing the type of propertyFollowed to String, int and long.

zaki50 commented 8 years ago

Can you print the propertyId to make sure that the value of PrimaryKey is not duplicate.

Log.d("PropFollowed", String.valueOf(fav.getPropertyFollowed()) + "(" + fav.getPropertyId() + ")");

If the propertyId is not duplicate, it seems to be something wrong in Realm.

gintechsystems commented 8 years ago
11-18 22:53:15.490 9697-9856/com.droid.visneta D/PropFollowed: 1(539356ad9134b3)
11-18 22:53:15.490 9697-9856/com.droid.visneta D/PropFollowed: 1(546104793bbad3)
11-18 22:53:15.490 9697-9856/com.droid.visneta D/PropFollowed: 1(54a8226b3b52b33)
zaki50 commented 8 years ago

thanks!

gintechsystems commented 8 years ago

Np, do you know a version that might be working?

zaki50 commented 8 years ago
    public void testIssue1799() {
        List<PropertyObject> list = new ArrayList<PropertyObject>();

        final PropertyObject obj1 = new PropertyObject();
        obj1.setPropertyId("539356ad9134b3");
        obj1.setPropertyFollowed(1);
        list.add(obj1);

        final PropertyObject obj2 = new PropertyObject();
        obj2.setPropertyId("546104793bbad3");
        obj2.setPropertyFollowed(1);
        list.add(obj2);

        final PropertyObject obj3 = new PropertyObject();
        obj3.setPropertyId("54a8226b3b52b33");
        obj3.setPropertyFollowed(1);
        list.add(obj3);

        testRealm.beginTransaction();
        testRealm.copyToRealmOrUpdate(list);
        testRealm.commitTransaction();

        assertEquals(3, testRealm.where(PropertyObject.class).equalTo("propertyFollowed", 1).count());
    }

I wrote a simplified unit test and can't reproduce the issue on 0.84.1... Definition of PropertyObject is the same with yours except that @SerializedName is commented out.

zaki50 commented 8 years ago

Is final long favoritesCount = realmThread.where(PropertyObject.class).equalTo("propertyFollowed", 1).count(); located just after the committing the list? Or is there any chance to update these objects before obtaining the count?

gintechsystems commented 8 years ago

Yeah after.

Here is the code:

JsonArray favorites = o.getAsJsonArray("follow");

Realm realmThread = Realm.getDefaultInstance();

List<PropertyObject> favsList = new ArrayList<>();
for (int i = 0; i < favorites.size(); i++) {
    if (!visnetawrap.isUserLoggedIn) {
        return null;
    }
    PropertyObject fav = visnetawrap.gsonClient.fromJson(favorites.get(i).toString(), PropertyObject.class);
    favsList.add(fav);
}
realmThread.beginTransaction();
realmThread.copyToRealmOrUpdate(favsList);
realmThread.commitTransaction();

final long favoritesCount = realmThread.where(PropertyObject.class).equalTo("propertyFollowed", 1).count();

            realmThread.close();
zaki50 commented 8 years ago

@gintechsystems You must close realmThread before return null;. It doesn't solve the problem though.

gintechsystems commented 8 years ago

Very strange case I agree, do not think it happened with previous Realm versions. I will attempt using an older release to see if it makes a difference for me.

Thank you for pointing that out, I will fix that.

gintechsystems commented 8 years ago

I was able to figure it out, I have code that runs after that pulls in nearby properties, apparently the same ones that are followed are that list but it was overwriting the propertFollowed.

List<PropertyObject> propsList = new ArrayList<>();
for (int i = 0; i < properties.size(); i++) {
    if (!visnetawrap.isUserLoggedIn) {
        return null;
    }
    PropertyObject prop = visnetawrap.gsonClient.fromJson(properties.get(i).toString(), PropertyObject.class);
    propsList.add(prop);
}
realmThread.beginTransaction();
realmThread.copyToRealmOrUpdate(propsList);
realmThread.commitTransaction();

That runs after the code I showed you but for some reason it overwrites the propertyFollowed, should I maybe create a different RealmObject for followed properties? It seems annoying to have to have 2 different RealmObjects when they would both contain the same definition, only difference would be if it was followed or not.

zaki50 commented 8 years ago

If you'd like to share the definition, you must use different value for propertyId since that field is the primary key.

For example,

List<PropertyObject> favsList = new ArrayList<>();
for (int i = 0; i < favorites.size(); i++) {
    PropertyObject fav = visnetawrap.gsonClient.fromJson(favorites.get(i).toString(), PropertyObject.class);
    fav. setPropertyId("fav:" + fav.getPropertyId());
    favsList.add(fav);
}

If #1129 (composite primary keys) will be implemented, we will be able to add another primary key such as int type.

gintechsystems commented 8 years ago

Hmmm alright but then there would be duplicates, correct?

For example, I can search properties in my app and also view favorites. I assume if the user searches the app, they will see 2 of them.

It might be easier just to create a separate RealmObject for now until that feature is implemented.

I noticed for Realm iOS this does not happen btw.

One last thing I noticed is if the json string that is being used to update the object does not contain a certain property it should not automatically overwrite it to null?

zaki50 commented 8 years ago

Yes.

If you are absolutely sure that all values other than propertyFollowed are the same,

public class FollowedValue extends RealmObject {
    private value;
    // setters and getters
}

public class PropertyObject extends RealmObject {
    @PrimaryKey
    @SerializedName("id")
    private String propertyId;

    ...

    private FollowedValue followdFromFavorites;
    private FollowedValue followdFromProperties;
}

In this definition, you can keep both values. But it needs more codes to maintain the data.

gintechsystems commented 8 years ago

Yeah I am sure, I use copyToRealmOrUpdate because if any of the data does change in the property, it will update that info the next time the user opens the app but hoping not to touch followed. So the user can always see the updated info.

Thank you for this, I appreciate all the help.

zaki50 commented 8 years ago

@gintechsystems I'll close this issue. If you have further questions, please reopen this or create new issue.

gintechsystems commented 8 years ago

I have discovered that the real issue here is GSON. If a value is missing from a JSON string it will set the field to null. Is there a way to override this and just skip the field instead of setting it to null?

From the documentation of GSON: While deserialization, a missing entry in JSON results in setting the corresponding field in the object to null

saket commented 8 years ago

@gintechsystems Consider using a different JSON library. GSON works nicely for most of the projects, but is very limited.

I'd suggest using LoganSquare. Apart from mapping directly to fields, JSON keys can also be mapped to setters.

gintechsystems commented 8 years ago

Thanks @Saketme I will check that lib out. For no here is my workaround:

.registerTypeAdapter(PropertyObject.class, new JsonDeserializer<PropertyObject>() {
                    @Override
                    public PropertyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                        PropertyObject prop = new PropertyObject();
                        JsonObject propObj = json.getAsJsonObject();

                        if (propObj.get("id") == null) {
                            return null;
                        }

                        prop.setPropertyId(propObj.get("id").getAsString());

                        if (propObj.get("followed") == null) {
                            Realm realmThread = Realm.getDefaultInstance();

                            PropertyObject existingProp = realmThread.where(PropertyObject.class).equalTo("propertyId", propObj.get("id").getAsString()).findFirst();
                            if (existingProp == null) {
                                prop.setPropertyFollowed(0);
                            }
                            else {
                                prop.setPropertyFollowed(existingProp.getPropertyFollowed());
                            }

                            realmThread.close();
                        }
                        else {
                            prop.setPropertyFollowed(propObj.get("followed").getAsInt());
                        }

                        return prop;
                    }
                })
saket commented 8 years ago

Should work if you've small JSON models :)