Forum Stats

  • 3,769,989 Users
  • 2,253,043 Discussions
  • 7,875,261 Comments

Discussions

Evolve DataBase

530677
530677 Member Posts: 31
edited Sep 12, 2006 11:26PM in Berkeley DB Java Edition
How can I do to evolve the db of my system?

For example, I had a class with some attributes, see the example:

...
private String name;
private Integer age;
...

and now I want remove the "Integer age" attribute and add the "String hairColor".

When I make this change in the class and in the bind interface of this class, JE returns to me Java exception, like a OutOfBounds Exception.

What is the correct form to change my DataBase?
«1

Comments

  • Greybird-Oracle
    Greybird-Oracle Member Posts: 2,690
    Hi,

    I assume you are using the (DPL) Direct Persistence Layer. If that is not correct, please let me know.

    In the DPL beta release, class evolution is not supported. It will be fully supported in the final release. This is mentioned in the release notes, the Javadoc, and the Getting Started Guide.

    For now, in order to change your DPL persistent classes, you will need to delete the environment (delete all files in your environment directory) and start from scratch.

    Mark
  • 530691
    530691 Member Posts: 1
    Hi Mark,

    could you estimate when you are going to release the final version of DPL?

    Thanks in advance,

    Marc
  • 530677
    530677 Member Posts: 31
    Hi Mark,

    I think that I'm not using this resource, I'm using the 2.1.30 version of Java BerkeleyDB.

    I'm using custom tuple bindings to persist the data. I'm sorry to not put all information in the last post message.
  • Greybird-Oracle
    Greybird-Oracle Member Posts: 2,690
    edited Aug 29, 2006 7:43PM
    Hi Hugo,

    For custom tuple bindings, if you need to support arbitrary changes to your class, the best approach is to write a version number as the first item in the data. Then when you read the tuple, you first read the version and that tells you how to interpret the remaining items in the tuple. The version number would be incremented each time you change the class, and your code would have to know how to read each version that might exist in the database. In other words, it is up to you to implement versioning.

    There is one simple case where it is easy: adding fields. In this case, always write the new fields at the end of the tuple. When reading the tuple, you can call TupleInput.available() to determine if you have reached the end of the items -- this method will return zero in that case. When you read a record that does not contain all fields, you can initialize the missing fields to default values.

    There is an FAQ on adding fields to a tuple here:

    http://www.oracle.com/technology/products/berkeley-db/faq/je_faq.html#7

    In the case you describe -- removing 'age' and adding 'hairColor' -- you have two choices:

    1) Add a version number and implement versioning of the data. If you have any data currently in production, you'll need to update all records with a conversion program in order to ensure that all records have a version number.

    2) Don't delete 'age' from the data -- instead continue to read and write it even though you don't use it. (Yes, the space taken by 'age' field will be wasted.) Add 'hairColor' at the end of the items as described above.

    Does this help?
    Mark
  • 530677
    530677 Member Posts: 31
    Mark,

    I´m understood, thanks. But if I set String type for all attributes in TupleBind, I will always insert String to the database, and when I need get it and populate my Data Object I will create new Objects based in data String, the problem is that when the format of String is not compatible with the Object that is need to be create. For example the value "123c" if I try create a new Double object, the JVM will throw exceptions to me. What I should do, is catch the exception and set the value with start value of object kind.

    What you think about it? You think that it is so crazy?
  • No, I'm afraid that won't work reliably. There is always the possibility that a binary numeric value will happen to look like a string, or a string will happen to look like a binary numeric value. In general, trying to recognize an older class version by the values in the record is quite dangerous. It may work for one particular situation, but I do not recommend using it as a general solution.

    Mark
  • Hi Marc,

    We're aiming for end of September for the final DPL release, but please understand that we can't commit to that date.

    Mark
  • 530677
    530677 Member Posts: 31
    Mark,

    this is the example that I´m thinking.

    look the example (Original classes):

    public class Person {
    private Integer age;
    private String name;

    //Getters and Setters here...
    }

    public class PersonBinding extends TupleBinding {
    public void objectToEntry(Object object, TupleOutput to) {
    Person person = (Person) object;

    to.writeString(person.getAge().toString());
    to.writeString(person.getName());
    }

    public Object entryToObject(TupleInput ti) {
    Person person = new Person();

    person.setAge(new Integer(ti.readString()));
    person.setName(ti.readString());
    }

    }


    now look the example (Changed classes):

    public class Person {
    private String hairColor;
    private String name;

    //Getters and Setters here...
    }

    public class PersonBinding extends TupleBinding {
    public void objectToEntry(Object object, TupleOutput to) {
    Person person = (Person) object;

    to.writeString(person.getHairColor());
    to.writeString(person.getName());
    }

    public Object entryToObject(TupleInput ti) {
    Person person = new Person();

    person.setHairColor(ti.readString());
    person.setName(ti.readString());
    }

    }


    So, I will always write String in database.
  • Hi Hugo,

    If the two strings stored in the database tuple are 'age' followed by 'name', and you execute this code:

    person.setHairColor(ti.readString());
    person.setName(ti.readString());

    That code will read the 'age' value into the hair color field, because 'age' is the first string in the existing records that were written by the old code. That's not what you wanted, right?

    Mark
  • 530677
    530677 Member Posts: 31
    Hi Mark!

    Yes, you has reason. I would need some engine to remove (clean) all data from this position to do it. Exist any engine into JE to clean specific data from all registers? If no I can create one engine to do it. Its is easy, I get all registers from db, change this position to "" (empt) and write this again. I can create one XML file to reconfigure the DB.

    Mark, there are performance problems if I uses only String values in DB?
This discussion has been closed.