Discussions

General J2EE: JDOQL flaws

  1. JDOQL flaws (1 messages)

    Hi all,

    I would like to see a true object querying system in JDO 2.0. Maybe Gavin King can speak for me. In my opinion the current JDOQL is a complete disaster. A quote from one of my postings to the microsoft.public.objectspaces newsgroup should point out some of my reasons.

    Assuming I have the following class model:

    class Person {
        String firstName;
        String lastName;
    }

    class Book {
        Person[] authors;
        String title;
    }

    Now I am looking for all authors of books that either you or I have contributed to and I want the book's name to begin with "JDO". Furthermore, let's assume that the strings to constrain the query are already contained in the following five variables:

    String title = "JDO";
    String carl = "Carl";
    String rosenberger = "Rosenberger";
    String christiaan = "Christiaan";
    String desBouvrie = "des Bouvrie";

    ObjectSpaces
    ------------
    It doesn't work. I can't contstrain a Query with an attribute of the Book type and look for objects of the type Person. A workaround: I get the Book objects and iterate through them. The overhead doesn't matter if the resultset is small but in practice it's essential to reduce fetchgroup traffic for good performance. There also may be deeper hierachies than just one book.authors step.

    String oPath =
     "name LIKE ?
      && (authors[firstName = ? && lastName = ?]
      || authors[firstName = ? && lastName = ?])";
    ObjectQuery oq = new ObjectQuery(typeof(Book), oPath);
    ObjectReader reader = objectSpace.GetObjectReader(
      oq, new Object[] {
        title + "%",
        carl,
        rosenberger,
        christiaan,
        desBouvrie
    });
    ArrayList persons = new ArrayList();
    foreach(Book b in reader){
      foreach(Person p in b.authors){
        persons.add(p);
      }
    }
    reader.Close();
    return persons;


    JDO
    ---
    /* The same problem as with ObjectSpaces. I can't get Person objects if I want to constrain Book attributes. The same workaround. By the way, "like" is not avaible in standard JDO, so I have to use the TJDO extension "String.startsWith".


    String vars = "Person cr, Person cdb";
    String params = "String title, String carl, String rosenberger,
      String christiaan, String desBouvrie";
    String filter =
     "String.startsWith(title) &&
      (authors.contains(cr) &&
      cr.firstName == carl &&
      cr.lastName == rosenberger &&
      authors.contains(cdb) ||
      cdb.firstName == christiaan &&
      cdb.lastName == desBouvrie";
    Extent eBooks = persistenceManager.getExtent(Book.class, false);
    Query q = persistenceManager.newQuery(eBooks, filter);
    q.declareParameters(params);
    q.declareVariables(vars);
    Collection books = (Collection)q.execute(
      new Object[]{
        title,
        carl,
        rosenberger,
        christiaan,
        desBouvrie
      }
    );
    List list = new ArrayList();
    Iterator it = books.iterator();
    while(it.hasNext()){
      Book book = (Book)it.next();
      for(int i = 0; i < book.authors.length, i++){
        list.add(book.authors[i]);
      }
    }
    return list;


    Clearly, both of the above use very ugly string constructs and I don't see how APIs like this can challenge SQL.

    However I do think that an object querying API can be extremely useful to make querying easier from OO languages, if it satisfies the following requirements:

    - Strings should be omitted where possible. Strings cause typos, they can't be refactored by IDEs, they use more ressources than objects and they are slower. Last but not least they require the vendor to write a string parser.

    - It's essential to allow any existing object to be reused in query criteria. Query-by-Example is the most natural way to query for objects.

    - The API should allow queries to be built step-by-step in multiple modules, so a high amount of code-reuse is possible.


    For our Java/.NET object database engine "db4o" we have tried to create such an API, it's called S.O.D.A. (Simple Object Database Access).

    Here is a S.O.D.A. solution for the above example:

    S.O.D.A. (db4o)
    ---------------
    Query qBooks = db.query();
    qBooks.constrain(typeof(Book));
    qBooks.descend("title").constrain(title).like();
    Query qAuthors = qBooks.descend("authors");
    Query qFirstName = qAuthors.descend("firstName");
    Query qLastName = qAuthors.descend("lastName");
    Constraint cCarl =
      qFirstName.constrain(carl).and(
      qLastName.constrain(rosenberger)
      );
    Constraint cChristiaan =
      qFirstName.constrain(christiaan).and(
      qLastName.constrain(desBouvrie)
    );
    cCarl.or(cChristiaan);
    return qAuthors.execute();


    Feel free to download a db4o trial version from our website to experiment with db4o. A regression test suite with more than 500 S.O.D.A. examples is included with the download.
    http://www.db4o.com

    I know that lot's of O/R-mapper vendors are reading along here and probably all of you have read Frans' rant against Microsoft's, ObjectSpaces policy. Maybe we should get together to think about our own standard that works a little different. Definitely we can beat MS' ugly "OPath" querying system.

    S.O.D.A. is intended to be an open source standard and everyone is free to use it or to contribute:
    http://sourceforge.net/projects/sodaquery/


    In my opinion it's quite simple to exchange object persistence systems, transparent or not. Run a different enhancer, write a different wrapper, use a different ClassLoader, all this can be done in a few days, even for huge applications.

    However it's a pain to exchange the complete querying system of an application. A perfect querying system has to be the first and foremost basis for any standard on object persistence.


    Kind regards,
    Carl
    --
    Carl Rosenberger
    db4o - database for objects
    http://www.db4o.com

    Threaded Messages (1)

  2. No opinions here?[ Go to top ]

    Well, since nobody replies here, I guess either nobody is using JDO or all of you are happy with the present JDO query implementation. I am not and I think the theme is important enough that anyone with an opinion should get involved. The discussion is being continued on JDOCentral. Here is the thread.