Francesco Galgani
Francesco Galgani

Reputation: 6249

Store to JSON a PropertyBusinessObject containing a ListProperty

I have difficult to store to JSON a PropertyBusinessObject containing a ListProperty. I created the following test case, that works fine on the first execution, but fails on the second. Is my code wrong?

My test case if composed by four classes:

TestCaseJSON

public void init(Object context) {
    [...]       

    DB.initPersistenceDB();
}

public void start() {
    if(current != null){
        current.show();
        return;
    }
    Form hi = new Form("Hi World", BoxLayout.y());
    hi.add(new Label("Hi World"));
    hi.show();

    DB.userDB.uniqueID.set("1");
    DB.userDB.authToken.set("myToken");
    InjuryDAO newInjury = new InjuryDAO();
    DB.userDB.injuries.add(newInjury);
    DB.saveDB();
}

DB

public class DB {

    // User Database
    public static UserDB userDB = new UserDB();

    /**
     * Call this method in the init(), it allows the database persistence and
     * automatically restores the saved DB.
     */
    public static void initPersistenceDB() {
        Log.p("DB.initPersistenceDB executing", Log.DEBUG);
        restoreDB();
    }

    /**
     * Saves the UserDB to the Storage
     */
    public static void saveDB() {
        Log.p("DB.saveUserDB executing", Log.INFO);
        userDB.getPropertyIndex().storeJSON("UserDB");
    }

    /**
     * Restore the UserDB from the Storage, if it was previously saved to; this
     * method is called by initPersistenceDB()
     */
    private static void restoreDB() {
        Log.p("DB.restoreUserDB executing", Log.INFO);
        if (Storage.getInstance().exists("UserDB")) {
            userDB.getPropertyIndex().loadJSON("UserDB");
        }
    }

}

UserDB

public class UserDB implements PropertyBusinessObject {

    public final Property<String, UserDB> uniqueID = new Property<>("uniqueID", null);
    public final Property<String, UserDB> authToken = new Property<>("authToken", null);

    public final ListProperty<InjuryDAO, UserDB> injuries = new ListProperty<>("injuries");

    public final PropertyIndex idx = new PropertyIndex(this, "UserDB",
            uniqueID, authToken,
            injuries
    );

    @Override
    public PropertyIndex getPropertyIndex() {
        return idx;
    }

}

InjuryDAO

public class InjuryDAO implements PropertyBusinessObject {

    // extra info
    public final LongProperty<InjuryDAO> injuryCreationTime = new LongProperty<>("injuryCreationTime", System.currentTimeMillis());

    // mandatory info
    public final Property<Date, InjuryDAO> dateInjury = new Property<>("dateInjury", Date.class);


    private final PropertyIndex idx = new PropertyIndex(this, "InjuryDAO",
            injuryCreationTime, dateInjury
    );

    @Override
    public PropertyIndex getPropertyIndex() {
        return idx;
    }

}

Before executing in the Simulator, I cleared the .cn1 directory (that is equivalent to Simulator, Clean Storage).

After the first execution, this is the log:

[EDT] 0:0:0,110 - DB.initPersistenceDB executing
[EDT] 0:0:0,110 - DB.restoreUserDB executing
[EDT] 0:0:0,178 - DB.saveUserDB executing

and this is the content of the UserDB file inside the .cn1 directory:

{
  "injuries": [{"injuryCreationTime": 1558202520667}],
  "authToken": "myToken",
  "uniqueID": "1"
}

That's correct.

After the second execution, the log is identical to the previous one, but this is the wrong content of the UserDB file (note that the previous time stamp is lost):

{
  "injuries": [
    {"injuries": []},
    {"injuryCreationTime": 1558202625655}
  ],
  "authToken": "myToken",
  "uniqueID": "1"
}

The expected correct result should be:

{
  "injuries": [
     {"injuryCreationTime": 1558202520667},
     {"injuryCreationTime": 1558202625655}
   ],
  "authToken": "myToken",
  "uniqueID": "1"
}

Thank you for your support.

Upvotes: 1

Views: 42

Answers (1)

Shai Almog
Shai Almog

Reputation: 52770

I think this:

public final ListProperty<InjuryDAO, UserDB> injuries = new ListProperty<>("injuries");

Should be changed to:

public final ListProperty<InjuryDAO, UserDB> injuries = new ListProperty<>("injuries", InjuryDAO.class);

If this doesn't work try:

public final ListProperty<InjuryDAO, UserDB> injuries = new ListProperty<>("injuries", InjuryDAO.class, null);

Upvotes: 1

Related Questions