Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
Developer
Posts: 91
Registered: ‎02-04-2009
My Device: Not Specified
Accepted Solution

Best Practices for Storing Application Configuration and Data

I am developing an application that gives users control over some configuration information.  The configurable options can be represented by integers or booleans.  Users can also create and manipulate data, which I represent internally using a number of classes that are fairly simple in terms of internal variables.  I'm wondering what the best approach for storing this information is?

 

Currently, the classes with data I care about implement Persistable and I use PersistentStore to write out the objects, but I'm concerned that I'll eventually have change the structure of the underlying classes, which would cause users to lose their data due to incompatibility.  I've considered continuing to use PersistentStore and writing out primitives instead of objects.  I would then have to implement factory methods to reconstruct the objects.  I know that persistent objects are removed when the classes are removed.  It seems like the data is wiped if the stored classes are incompatible with the current classes.  Are there any other situations where the data is erased?  What happens if storage runs low?  What if my classes stay the same, but the rest of my applications grows larger with new functionality or shrinks with removed features?  Does that have an effect on data?

 

Another option would be to use RecordStore, but that API just looks like a nightmare.  Storing data files and then parsing them at startup is an alternative too, but I'm curious what happens to files during upgrades or uninstalls.

 

My requirements are persistence and the ability to maintain backwards compatibility.  I'd appreciate any comments.  Thanks.

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

We use the persistent store for this type of data. we place a version number in the store which is checked at startup. This gives us the ability to migrate the store to a new schema on an upgrade.

 

Developer
Posts: 91
Registered: ‎02-04-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

I'm assuming you are writing out standard data types (e.g., Integer, Boolean, Vector, etc.) instead of custom classes (e.g., Foo, Bar, etc.).  Is that correct?  How complex is your data?  What class are using to package your data when you store it?  I'm considering an IntHashtable.

 

Internally, my data is stored as a Vector of Foo objects.  Each Foo object has an IntHashmap with ints as keys and AbstractBar objects as values.  There are only five subclasses of AbstractBar now, but we expect to add a few more in the future.  I haven't found a nice way to handle the subclasses when I store the data.

 

Maybe I could do something like this where, for example, VERSION is the key and the value is an Integer.  When it's time to construct my subclasses of AbstractBar, I'd check the value at CLASS and do things dynamically.  It's ugly.

 

VERSION: Integer

CONFIG_1: Integer

CONFIG_2: Boolean

... 

DATA: Vector

  DATA[0]: Hashmap?

    CLASS: String

    VAR1: Integer

    VAR2: Boolean

    ...

  DATA[1]: Hashmap?

    CLASS: String

    VAR1: String

    VAR2: Long

    ... 

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

I agree with RexDoug's comments.  Sorry I don't understand what you are suggesting with AbstractBar, so I can't make any comment on that.

 

I wanted to share an interesting option suggested by RIM at DevCon, which is similar to RexDoug's versioning idea.  You store the data in class Foo.  If you need to dramatically change the structure of class Foo, then you persist a new class called Foo2.  If you extract an object of type Foo from the Persistent Store, you migrate it to Foo2, and then persist Foo2 in place of Foo.

 

I must admit, when dramatic changes have taken place with our persisted data, we have taken the approach that it is better to get the user to completely reinstall and repopulate the data   For minor changes, we try to accommodate these within the exiting objects, by adding native objects at specified vector locations or extending arrays.  For example, if you have an array of ints, and you need to store another int in the Object, then you can add another element to the array without changing the signature of the persisted data.

Developer
Posts: 91
Registered: ‎02-04-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

I'll try to clarify a bit.  I have a list of Foo objects.  Each Foo object has a a few basic fields (int, boolean, etc.) and some objects of type AbstractBar.  AbstractBar is an abstract class with a few subclasses (e.g., ConcreteBar1, ConcreteBar2, etc.).  I can set up the basic fields of Foo easily enough, but creating the AstractBar objects is complicated because I have to know which of the subclasses to use.  Is that more clear?

 

Do you have any links that talk about the Foo2 approach that RIM discussed?  That was an approach I considered originally, but I was worried about having lots of unused classes lying around in the future. 

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

Custom Persistable classes are ticking maintenance time-bombs. First of all, if a custom Persistable class all of a sudden becomes incompatible with its previous version, the module containing the new version of the class may not install OTA (e.g., downloads via the BlackBerry web browser used to fail for multi-COD JADs) and, even if it installs, the persistent data is lost. Secondly, if the module is removed, the persistent data is removed (sometimes it's a good thing, sometimes it's a bad thing -- some administrators (mis)configure BES OTA Push to first remove old modules, and then install the new ones). Thirdly, if a custom Persistable class is no longer needed, it cannot be removed, because doing so will render the module incompatible with its installed version and hence the upgrade might fail OTA.

 

The most annoying thing about custom Persistable classes is that RIM provide no guarantees as to what changes to a class are safe (i.e., don't break its backward-compatibility). I saw cases where changing as little as one line of code inside a method of a custom Persistable class would render the class incompatible.

Developer
Posts: 91
Registered: ‎02-04-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

klyubin, what do you use instead of custom Persistable classes?
Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

Built-in Persistable classes such as Hashtables, Vectors, arrays, and the likes. It's slower, uses more memory, and provides weaker typing, but if it's for storing settings, then it doesn't matter. If you want your settings to be automatically removed when the app is removed, you can store you own custom Persistable object that only contains one field: a reference to a built-in Persistable container (Hashtable is a good start) built solely from built-in Persistable objects. Also, as mentioned earlier, it still is a very good idea to store a "schema" version number to make it easier to change the way settings are stored or interpreted.
Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

Sorry I don't have a link to the suggestion by RIM for a second class - it was discussed in a presentation, and I'm sorry I can't find the slide.

 

While I do understand the points made by klyubin, I think they can be managed and I think the fact that custom persistent classes will be removed when the application is removed is a good thing. 

 

I don't understand the comment about it being impossible to remove a custom Persistable class - is this the data object or the class?

 

I also have never experienced code in a custom class causing a problem.  In fact I happily change the accessors to persistent objects without worrying about compatibility.  

 

As an example of a custom Persistent Object, let us imagine our Persistent Object is a Vector, that we have extended, but we are initially only storing 1 String in it, the userid.

 

So we have our persistent object defined simply as

 

class OurPersistentObject extends Vector {

 

public String getUserid() {

return (String) this.elementAt(0);

}

 

public void setUserid(String newUserid) {

this.setElementAt(newUserid, 0);

}

 

}

 

Now of course, we can easily add the password to this Object, without breaking it, by simply adding it at index 1 and creating appropriate accessor routines for it.

 

With a bit of thought like this, I think it is relatively easy to write extensible custom persistent classes.  But that is just me.....

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Best Practices for Storing Application Configuration and Data

[ Edited ]

I meant that it's impossible to remove a custom Persistable class from a module because doing so makes the module incompatible with its previous version. If I recall correctly, this is the case even when there are no instances of the custom Persistable class stored in the PersistentStore on the device. It's possible to carefully throw away most of the code of the custom Persistable class and leave behind only a skeleton that keeps the compatibility verifier happy though.

 

Persistable classes declared "final" were more likely to become incompatible when the bodies of their methods were modified (might be due to inlining by the compiler though). Also, I haven't dealt with custom Persistable classes that extend built-in Persistable classes. This might explain why my experience has been so different from that of peter_strange.

 

Everything I've said in this thread pertains to experiences with 4.3 and earlier. I haven't used custom Persistable classes on 4.5+.

Message Edited by klyubin on 04-24-2009 08:12 PM
Message Edited by klyubin on 04-24-2009 08:24 PM