首页 > 解决方案 > 将包含 ListProperty 的 PropertyBusinessObject 存储到 JSON

问题描述

我很难将PropertyBusinessObject包含一个ListProperty. 我创建了以下测试用例,它在第一次执行时运行良好,但在第二次执行时失败。我的代码错了吗?

我的测试用例由四个类组成:

测试用例JSON

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();
}

D B

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");
        }
    }

}

用户数据库

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;
    }

}

伤害道

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;
    }

}

在Simulator中执行之前,我清空了.cn1目录(即相当于Simulator,Clean Storage)。

第一次执行后,这是日志:

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

这是目录UserDB内文件的内容.cn1

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

这是正确的。

第二次执行后,日志与前次相同,但这是UserDB文件内容错误(注意前次时间戳丢失)

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

预期的正确结果应该是:

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

谢谢您的支持。

标签: codenameone

解决方案


我认为这:

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

应改为:

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

如果这不起作用,请尝试:

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

推荐阅读