[This text is only available in english so far.]

Efficient Java-Database Application Development

Hiding SQL by using the Invoca Java-Database Objectrelational Mapping:

The Invoca OR-Mapping technology is a fully automated toolkit which transforms database metadata into java classes with the complete functionality needed to develop elegant database applications.

Instead of writing code like this:

    Class.forName(<jdbcDriver>);
    java.sql.Connection con =
          DriverManager.getConnection(<jdbcURL>,
          <dbUID>, <dbPWD>);
    Statement stmt = con.createStatemen();
    stmt.executeQuery("INSERT INTO ITEM"
          +" (ITEMNUMBER, DESCRIPTION, PRICE)"
          +" VALUES (1234, 'Chair, red', 55.00)");
    ...
    stmt.executeUpdate("UPDATE ITEM"
          +" SET PRICE=PRICE+1"
          +" WHERE ITEMNUMBER=1234")
we simply need to write the following piece of code:
    ITEM item = new ITEM();
    item.colITEMNUMBER  = new BigDecimal(1234);
    item.colDESCRIPTION = "Chair, red";
    item.colPRICE       = new BigDecimal("55.00");
    item.insert();
    ...
    item.colPRICE = item.colPRICE.add(
                         new BigDecimal(1));
    item.update();

Integrated Features:

  • Automated Generation of all java source and class files for all [optionally selected] Tables. This generation step can be integrated programmatically into the buildprocess for the project.
  • Integration of Userdefined Code: Each Java Source File contains a region of 'protected code' which is used to place logical code or other userdefined functionality. This area is untouched during the generation process above.
  • Reference-Support: The Framework supports referential integrity, which means for example the ability to retrieve one single ADDRESS-Instance (one row of the table ADDRESS) which is referenced by an ORDER with the following method (=many-to-one relationship):

      ADDRESS address = order.toRefADDRESS();

    In a similar way it is possible to retreive all ITEMS referenced by one ORDER (=one-to-many relationship):

      ITEM[] items = order.toRefAllITEM(int maxRows,
                                        boolean ad);


    where the parameters maxRows and ad (additional denied) limit the result to avoid the reading of rows the application never really uses.
  • Caching Mechanisms: The semantically correct implementation of the equals and hashCode-Methods provide an easy support for various userdefined caching-mechanisms.
  • Support for recursively defined data structur: Recursive Data Structures usually define a tree, while each element of the tree is stored in one row of the same table and the table contains a foreign key that points to the primary key of the same table. In this case the foreign key coulmn[s] contain[s] the value[s] of the primary key column[s] of his parent-element. Our persistence framework provides a mechanism to automatically read the recursively defined data into a tree structure.
  • Automatically generated Keys even with several keyColumns. The following code shows how it works:
    Let's suppose that the ORDER-Table contains the following columns: ORDERNUMBER, ADDRESSNUMBER and ORDERDATE and the code should insert a new order for the client whose address is saved in the row with ADDRESSNUMBER=555:

      // reads the specified row automatically:
      ADDRESS address = new ADDRESS(
                 new BigDecimal("555"));
      // create a new order-Object (in java only):
      ORDER order = new ORDER();
      // apply the values defined by referential
      // integrity to the order-Object:
      order.setRefCols(address);
      // and finally insert the order
      // into the database:
      order.insertAsNext();

    In this exaple the line 'order.setRefCols(address);' is actually doing the same as 'order.colADDRESSNUMBER = address.colADDRESSNUMBER' since this column is used by the database for the referential integrity.
    Like other data manipulation, the method 'insertAsNext() runs as 'atomic operation' what means that the key generation runs as one transaction sequence. The default implementation will generate the subsequent ordernumber [max(ordernumber)+1] as the next key. This behaviour can be changed by overriding the method that defines the default behaviour.
  • Transaction-based manipulation of Data: An update-operation for example takes place as 'atomic operation'. This means that before an update is done, the specified row is read again from the database and compared to the old values cached within each Persistent instance (like order in our prvious example). If the values have been changed by another user [or another application] the framework avoids the update operation (that would make the previous uptdate to a 'lost update'). Instead an Exception is thrown that indicates that the values have been changed.
  • Database-Java Mapping: The relationship between Database Elements and their mapped counterparts within the java environment is shown in the following table:
    Database ObjectsJava Mapping
    Table (eg. 'ITEM') Java Class (src: 'ITEM.java')
    Column of a Table (eg. PRICE of table ITEM) Field of Class (ITEM.colPRICE)
    Foreign Key (Referential Integrity Rule) Innerclass within the main class
    Execution of an Insert-Statement Call of the method 'insert()'
    Update-Statement Method 'update()'
    Delete-Statement Method 'delete()'
    Selection of all rows of the table ITEM referenced by one row of the table ORDER. ORDER order =
        new ORDER(new BigDecimal("1000"));
    ITEM[] items =
        order.toRefAllITEM();

Using this framework brings several advantages:

  • Development of code is much simpler, more elegant, clearer and easyer to maintnance.
  • RuntimeExceptions caused by the use of wrong data types are avoided. (Example: Inserting values by an SQL-Statement causes a RuntimeException if for example a String ('1') is set instead of a Number (1). In some cases the use of prepared statements avoid this problem, too.). Using our Persistence Framework prevents the developer from doing mistakes of that kind even earlier:
    Normally the IDE supports type-checking. Thus a wrong expression like   item.colPRICE = "55.00";
    instead of
      item.colPRICE = new BigDecimal("55.00");
    will cause the IDE to show the user that the two types BigDecimal and String are incompatible.
  • The visibility of Databasetables as java classes as well as columns as java-fields and referential integrity rules as inner classes (and String constants) within the preferred IDE (Integrated development environment) avoids mistakes during develpment.
  • A change of a table- or columnname for example will never keep the developer guessing about the question if the project still contains code that needs a change, too or a change within the code that was done was wrong. The replacement of these names within JavaCode [especially in a large project] is both difficult and a waste of time because it can't be done by a simple 'find & replace' on the project. Re-running the automatic code generation, more exactly the subsequent compilation - will show the developer exactly which part of code need a change. Or even better: if the used IDE supports refactoring (like IntelliJ for example), the change of a table- or columnname is a matter of two minuts.


copyright (c) Invoca Systems, Sägeweg 15, CH-4304 Giebenach