You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2022/01/25 09:56:04 UTC

[empire-db] branch version3 updated: EMPIREDB-362 DBRecord replace initRecord() with create(key)

This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/version3 by this push:
     new bc01bfa  EMPIREDB-362 DBRecord replace initRecord() with create(key)
bc01bfa is described below

commit bc01bfa004f6c802fd13c095c7f89bc2291e44e5
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Tue Jan 25 10:56:02 2022 +0100

    EMPIREDB-362 DBRecord replace initRecord() with create(key)
---
 .../org/apache/empire/samples/db/SampleApp.java    | 70 +++++++++++++++++-----
 .../org/apache/empire/samples/db/SampleBean.java   | 19 +++++-
 .../org/apache/empire/samples/db/SampleDB.java     | 55 ++++++++++++-----
 .../empire/vue/sample/db/records/SampleRecord.java |  2 +-
 .../main/java/org/apache/empire/db/DBCommand.java  |  4 +-
 .../java/org/apache/empire/db/DBCommandExpr.java   | 21 ++-----
 .../main/java/org/apache/empire/db/DBQuery.java    | 30 +---------
 .../main/java/org/apache/empire/db/DBRecord.java   | 12 ++--
 .../main/java/org/apache/empire/db/DBRowSet.java   | 60 +++++++++++--------
 .../main/java/org/apache/empire/db/DBTable.java    | 17 +-----
 .../src/main/java/org/apache/empire/db/DBView.java |  2 +-
 .../java/org/apache/empire/db/SerializeTest.java   |  4 +-
 .../empire/dbms/hsql/DBMSHandlerHSqlTest.java      |  5 +-
 13 files changed, 173 insertions(+), 128 deletions(-)

diff --git a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
index 43d05cf..0c4ce41 100644
--- a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
+++ b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
@@ -18,8 +18,11 @@
  */
 package org.apache.empire.samples.db;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.time.LocalDate;
 import java.util.List;
 
 import org.apache.empire.commons.StringUtils;
@@ -89,7 +92,7 @@ public class SampleApp
 			DBMSHandler dbms = getDBMSHandler(config.getDatabaseProvider(), conn);
 			
             // STEP 2.2: Create a Context
-			context = new DBContextStatic(dbms, conn, true, true); 
+			context = new DBContextStatic(dbms, conn, false, true); 
 
             // STEP 3: Open Database (and create if not existing)
             System.out.println("*** Step 3: openDatabase() ***");
@@ -130,6 +133,9 @@ public class SampleApp
 			int idEmp1 = insertEmployee("Peter", "Sharp", Gender.M, idDevDep);
 			int idEmp2 = insertEmployee("Fred", "Bloggs", Gender.M, idDevDep);
 			int idEmp3 = insertEmployee("Emma", "White",  Gender.F, idSalDep);
+            // Insert Payments
+			insertPayments(idEmp1, new BigDecimal(2000));
+			insertPayments(idEmp3, new BigDecimal(2500));
 
 			// commit
 			context.commit();
@@ -291,6 +297,8 @@ public class SampleApp
 	private static void clearDatabase()
     {
 		DBCommand cmd = context.createCommand(db);
+        // Delete all Payments (no constraints)
+        context.executeDelete(db.PAYMENTS, cmd);
 		// Delete all Employees (no constraints)
 		context.executeDelete(db.EMPLOYEES, cmd);
 		// Delete all Departments (no constraints)
@@ -312,7 +320,7 @@ public class SampleApp
 		rec.setValue(DEP.BUSINESS_UNIT, businessUnit);
 		rec.update();
 		// Return Department ID
-		return rec.getInt(DEP.DEPARTMENT_ID);
+		return rec.getInt(DEP.ID);
 	}
 
 	/**
@@ -332,9 +340,33 @@ public class SampleApp
 		rec.setValue(EMP.DEPARTMENT_ID, departmentId);
 		rec.update();
 		// Return Employee ID
-		return rec.getInt(EMP.EMPLOYEE_ID);
+		return rec.getInt(EMP.ID);
 	}
 
+    /**
+     * <PRE>
+     * Inserts an Payments for a particular Employee
+     * </PRE>
+     */
+    private static void insertPayments(int employeeId, BigDecimal monthlySalary)
+    {
+        SampleDB.Payments PAY = db.PAYMENTS;
+        // Insert an Employee
+        LocalDate date = LocalDate.now();
+        date = date.minusDays(date.getDayOfMonth()-1); // first day of this month
+        // Add Payment for each month
+        DBRecord rec = new DBRecord(context, PAY);
+        for (LocalDate month=date.minusMonths(20); !month.isAfter(date); month=month.plusMonths(1))
+        {
+            BigDecimal variation = new BigDecimal((Math.random()*200) - 100.0);
+            variation = variation.setScale(2, RoundingMode.HALF_UP);
+            // insert
+            rec.create(DBRecord.key(employeeId, month.getYear(), month.getMonth()));
+            rec.setValue(PAY.AMOUNT, monthlySalary.add(variation));
+            rec.update();
+        }
+    }
+
 	/**
      * <PRE>
 	 * Updates an employee record by setting the phone number.
@@ -360,7 +392,7 @@ public class SampleApp
         // Shortcut for convenience
         SampleDB.Employees EMP = db.EMPLOYEES;
         // Update an Employee with partial record
-        // this will only load the EMPLOYEE_ID and the PHONE_NUMBER
+        // this will only load the EMPLOYEE ID and the PHONE_NUMBER
         DBRecord rec = new DBRecord(context, EMP);
         EMP.readRecord(rec, DBRecord.key(idEmp), PartialMode.INCLUDE, EMP.PHONE_NUMBER);
         // Set
@@ -383,8 +415,8 @@ public class SampleApp
         DBCommand cmd = db.createCommand();
         cmd.select(EMP.getColumns());
         cmd.select(DEP.getColumns());
-        cmd.join(EMP.DEPARTMENT_ID, DEP.DEPARTMENT_ID);
-        DBQuery query = new DBQuery(cmd, EMP.EMPLOYEE_ID);
+        cmd.join(EMP.DEPARTMENT_ID, DEP.ID);
+        DBQuery query = new DBQuery(cmd, EMP.ID);
 
         // Make employee Head of Department and update salary
         DBRecord rec = new DBRecord(context, query);
@@ -435,7 +467,7 @@ public class SampleApp
         log.info("testTransactionCreate performed OK");
         context.commit();
         
-        return rec.getInt(EMP.EMPLOYEE_ID);
+        return rec.getInt(EMP.ID);
     }
     /**
      * @param context
@@ -513,7 +545,7 @@ public class SampleApp
      *   SELECT t2.EMPLOYEE_ID, t2.LASTNAME || ', ' || t2.FIRSTNAME AS FULL_NAME, t2.GENDER, t2.PHONE_NUMBER, 
      *          substr(t2.PHONE_NUMBER, length(t2.PHONE_NUMBER)-instr(reverse(t2.PHONE_NUMBER), '-')+2) AS PHONE_EXTENSION, 
      *          t1.NAME AS DEPARTMENT, t1.BUSINESS_UNIT
-     *   FROM EMPLOYEES t2 INNER JOIN DEPARTMENTS t1 ON t1.DEPARTMENT_ID = t2.DEPARTMENT_ID
+     *   FROM EMPLOYEES t2 INNER JOIN DEPARTMENTS t1 ON t1.DEPARTMENT_ID = t2.ID
      *   WHERE length(t2.LASTNAME)>0
      *   ORDER BY t2.LASTNAME, t2.FIRSTNAME
      * 
@@ -533,14 +565,18 @@ public class SampleApp
 	 */
 	private static void queryRecords(QueryType queryType)
     {
+        int lastYear = LocalDate.now().getYear()-1;
+	    
 	    // Define the query
 	    DBCommand cmd = db.createCommand();
 	    // Define shortcuts for tables used - not necessary but convenient
 	    SampleDB.Employees   EMP = db.EMPLOYEES;
 	    SampleDB.Departments DEP = db.DEPARTMENTS;
+        SampleDB.Payments    PAY = db.PAYMENTS;
 
 	    // The following expression concats lastname + ', ' + firstname
         DBColumnExpr EMPLOYEE_FULLNAME = EMP.LASTNAME.append(", ").append(EMP.FIRSTNAME).as("FULL_NAME");
+        DBColumnExpr PAYMENTS_LAST_YEAR = PAY.AMOUNT.sum().as("PAYMENTS_LAST_YEAR");
         
         // The following expression extracts the extension number from the phone field
         // e.g. substr(PHONE_NUMBER, length(PHONE_NUMBER)-instr(reverse(PHONE_NUMBER), '-')+2) AS PHONE_EXTENSION
@@ -552,17 +588,22 @@ public class SampleApp
              PHONE_LAST_DASH = EMP.PHONE_NUMBER.indexOf("-", EMP.PHONE_NUMBER.indexOf("-").plus(1)).plus(1); // HSQLDB only
         else PHONE_LAST_DASH = EMP.PHONE_NUMBER.length().minus(EMP.PHONE_NUMBER.reverse().indexOf("-")).plus(2);  
         DBColumnExpr PHONE_EXT_NUMBER = EMP.PHONE_NUMBER.substring(PHONE_LAST_DASH).as("PHONE_EXTENSION");
-        
+
         // DBColumnExpr genderExpr = cmd.select(EMP.GENDER.decode(EMP.GENDER.getOptions()).as(EMP.GENDER.getName()));
         // Select required columns
-        cmd.select(EMP.EMPLOYEE_ID, EMPLOYEE_FULLNAME);
+        cmd.select(EMP.ID, EMPLOYEE_FULLNAME);
         cmd.select(EMP.GENDER, EMP.PHONE_NUMBER, PHONE_EXT_NUMBER);
         cmd.select(DEP.NAME.as("DEPARTMENT"));
         cmd.select(DEP.BUSINESS_UNIT);
-        cmd.join(EMP.DEPARTMENT_ID, DEP.DEPARTMENT_ID);
+        // add payment of current year
+        cmd.groupBy(cmd.getSelectExprList());
+        cmd.select(PAYMENTS_LAST_YEAR);
+        // join
+        cmd.join(EMP.DEPARTMENT_ID, DEP.ID);
+        cmd.joinLeft(EMP.ID, PAY.EMPLOYEE_ID).where(PAY.YEAR.is(lastYear));
         // Set constraints and order
         cmd.where(EMP.LASTNAME.length().isGreaterThan(0));
-        cmd.orderBy(EMP.LASTNAME, EMP.FIRSTNAME);
+        cmd.orderBy(EMPLOYEE_FULLNAME);
 
         /*
         // Example for limitRows() and skipRows()
@@ -590,11 +631,12 @@ public class SampleApp
 			        // Text-Output by iterating through all records.
 	                while (reader.moveNext())
                     {
-	                    System.out.println(reader.getString(EMP.EMPLOYEE_ID)
+	                    System.out.println(reader.getString(EMP.ID)
 	                            + "\t" + reader.getString(EMPLOYEE_FULLNAME)
 	                            + "\t" + EMP.GENDER.getOptions().get(reader.getString(EMP.GENDER))
                                 + "\t" + reader.getString(PHONE_EXT_NUMBER)
-	                            + "\t" + reader.getString(DEP.NAME));
+	                            + "\t" + reader.getString(DEP.NAME)
+	                            + "\t" + reader.getString(PAYMENTS_LAST_YEAR));
 	                }
 			        break;
                 case BeanList:
diff --git a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleBean.java b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleBean.java
index 326513c..9db7ee8 100644
--- a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleBean.java
+++ b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleBean.java
@@ -18,6 +18,7 @@
  */
 package org.apache.empire.samples.db;
 
+import java.math.BigDecimal;
 
 /**
  * The SampleBean class is used to demonstrate JavaBean support for SQL-Queries.
@@ -31,12 +32,13 @@ public class SampleBean
     private String phoneNumber;
     private String department;
     private String businessUnit;
+    private BigDecimal paymentsLastYear;
 
     /*
      * Uncomment this if you want to use constructor instead of setters
-     * However, number of arguments and data types must match query!
+     * Number of arguments and data types must match query!
      *
-    public SampleBean(int employeeId, String fullName, String gender, String phoneNumber, String department, String businessUnit)
+    public SampleBean(int employeeId, String fullName, String gender, String phoneNumber, String department, String businessUnit, BigDecimal paymentsLastYear)
     {
         this.employeeId = employeeId;
         this.fullName = fullName;
@@ -44,6 +46,7 @@ public class SampleBean
         this.phoneNumber = phoneNumber;
         this.department = department;
         this.businessUnit = businessUnit;
+        this.paymentsLastYear = paymentsLastYear;
     }
     */
     
@@ -107,6 +110,16 @@ public class SampleBean
         this.businessUnit = businessUnit;
     }
 
+    public BigDecimal getPaymentsLastYear()
+    {
+        return paymentsLastYear;
+    }
+
+    public void setPaymentsLastYear(BigDecimal paymentsLastYear)
+    {
+        this.paymentsLastYear = paymentsLastYear;
+    }
+
     @Override
     public String toString()
     {
@@ -120,6 +133,8 @@ public class SampleBean
         buf.append(department);
         buf.append("\t");
         buf.append(businessUnit);
+        buf.append("\t");
+        buf.append(paymentsLastYear);
         return buf.toString();
     }
     
diff --git a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
index 3b9e70b..091272d 100644
--- a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
@@ -27,7 +27,7 @@ import org.apache.empire.db.DBTableColumn;
 /**
  * <PRE>
  * This file contains the definition of the data model in Java.
- * The SampleDB data model consists of two tables and a foreign key relation.
+ * The SampleDB data model consists of three tables and a foreign key relation.
  * The tables are defined as nested classes here, but you may put them in separate files if you want to.
  *
  * PLEASE NOTE THE NAMING CONVENTION:
@@ -41,8 +41,9 @@ import org.apache.empire.db.DBTableColumn;
  */
 public class SampleDB extends DBDatabase
 {
-    // *Deprecated* private static final long serialVersionUID = 1L;
-    
+    /**
+     * Gender enum
+     */
     public enum Gender
     {
     	M("Male"),
@@ -62,13 +63,11 @@ public class SampleDB extends DBDatabase
     }
 
     /**
-     * This class represents the definition of the Departments table.
+     * This class represents the Departments table.
      */
     public static class Departments extends DBTable
     {
-        // *Deprecated* private static final long serialVersionUID = 1L;
-      
-        public final DBTableColumn DEPARTMENT_ID;
+        public final DBTableColumn ID;
         public final DBTableColumn NAME;
         public final DBTableColumn HEAD;
         public final DBTableColumn BUSINESS_UNIT;
@@ -78,7 +77,7 @@ public class SampleDB extends DBDatabase
         {
             super("DEPARTMENTS", db);
             // ID
-            DEPARTMENT_ID   = addColumn("DEPARTMENT_ID",    DataType.AUTOINC,       0, true, "DEP_ID_SEQUENCE");
+            ID              = addColumn("DEPARTMENT_ID",    DataType.AUTOINC,       0, true, "DEP_ID_SEQUENCE");  // Sequence name only required for some DBMS (e.g. Oracle)
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
@@ -92,13 +91,11 @@ public class SampleDB extends DBDatabase
     }
 
     /**
-     * This class represents the definition of the Employees table.
+     * This class represents the Employees table.
      */
     public static class Employees extends DBTable
     {
-        // *Deprecated* private static final long serialVersionUID = 1L;
-      
-        public final DBTableColumn EMPLOYEE_ID;
+        public final DBTableColumn ID;
         public final DBTableColumn SALUTATION;
         public final DBTableColumn FIRSTNAME;
         public final DBTableColumn LASTNAME;
@@ -117,7 +114,7 @@ public class SampleDB extends DBDatabase
             super("EMPLOYEES", db);
             
             // ID
-            EMPLOYEE_ID     = addColumn("EMPLOYEE_ID",      DataType.AUTOINC,      0, true, "EMPLOYEE_ID_SEQUENCE");
+            ID              = addColumn("EMPLOYEE_ID",      DataType.AUTOINC,      0, true, "EMPLOYEE_ID_SEQUENCE");  // Sequence name only required for some DBMS (e.g. Oracle)
             SALUTATION      = addColumn("SALUTATION",       DataType.VARCHAR,     20, false);
             FIRSTNAME       = addColumn("FIRSTNAME",        DataType.VARCHAR,     40, true);
             LASTNAME        = addColumn("LASTNAME",         DataType.VARCHAR,     40, true);
@@ -138,19 +135,47 @@ public class SampleDB extends DBDatabase
         }
     }
 
+    /**
+     * This class represents the Payments table.
+     */
+    public static class Payments extends DBTable
+    {
+        public final DBTableColumn EMPLOYEE_ID;
+        public final DBTableColumn YEAR;
+        public final DBTableColumn MONTH;
+        public final DBTableColumn AMOUNT;
+
+        public Payments(DBDatabase db)
+        {
+            super("PAYMENTS", db);
+            
+            // ID
+            EMPLOYEE_ID     = addColumn("EMPLOYEE_ID",      DataType.INTEGER,      0, true);
+            YEAR            = addColumn("YEAR",             DataType.DECIMAL,    4.0, true);
+            MONTH           = addColumn("MONTH",            DataType.DECIMAL,    2.0, true);
+            AMOUNT          = addColumn("AMOUNT",           DataType.DECIMAL,    8.2, true);
+
+            // Primary Key (automatically set due to AUTOINC column)
+            setPrimaryKey(EMPLOYEE_ID, YEAR, MONTH);
+            // Set other Indexes
+        }
+    }
+    
     // Declare all Tables and Views here
     public final Departments  DEPARTMENTS = new Departments(this);
     public final Employees    EMPLOYEES   = new Employees(this);
+    public final Payments     PAYMENTS    = new Payments(this);
 
     /**
-     * Constructor of the SampleDB data model description
+     * Constructor of the SampleDB data model
      *
      * Put all foreign key relations here.
      */
     public SampleDB()
     {
         // Define Foreign-Key Relations
-        addRelation( EMPLOYEES.DEPARTMENT_ID.referenceOn( DEPARTMENTS.DEPARTMENT_ID ));
+        addRelation( EMPLOYEES.DEPARTMENT_ID.referenceOn( DEPARTMENTS.ID ));
+        addRelation( PAYMENTS.EMPLOYEE_ID   .referenceOn( EMPLOYEES.ID ));
     }
 
 }
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
index 323398e..a949588 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/records/SampleRecord.java
@@ -93,7 +93,7 @@ public abstract class SampleRecord<T extends SampleTable> extends DBRecord
         // load original record
         if (newRecord)
         {   // init a new record
-            super.init(key, true);
+            super.create(key);
         }
         else
         {   // read the current record
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
index 6315c9c..af24778 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
@@ -583,7 +583,7 @@ public abstract class DBCommand extends DBCommandExpr
      * 
      * @return the join expresion 
      */
-    public final DBColumnJoinExpr leftJoin(DBColumnExpr left, DBColumn right)
+    public final DBColumnJoinExpr joinLeft(DBColumnExpr left, DBColumn right)
     {
         return join(left, right, DBJoinType.LEFT);
     }
@@ -598,7 +598,7 @@ public abstract class DBCommand extends DBCommandExpr
      * 
      * @return the join expresion 
      */
-    public final DBColumnJoinExpr rightJoin(DBColumnExpr left, DBColumn right)
+    public final DBColumnJoinExpr joinRight(DBColumnExpr left, DBColumn right)
     {
         return join(left, right, DBJoinType.RIGHT);
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
index 1209532..b6d3d34 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
@@ -33,14 +33,10 @@ import org.apache.empire.exceptions.ObjectNotValidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
-
-
 /**
  * This abstract class handles the creation of the SQL-Commands.
  * There are inner classes to construct different SQL-Commands.
  * <P>
- * 
- *
  */
 public abstract class DBCommandExpr extends DBExpr
 {
@@ -133,35 +129,28 @@ public abstract class DBCommandExpr extends DBExpr
             throw new NotSupportedException(this, "getRecordKey");
         }
 
-        /** Returns the error message: ERR_NOTSUPPORTED */
-        @Override
-        public void initRecord(DBRecord rec, Object[] keyValues, boolean insert)
-        {
-            throw new NotSupportedException(this, "initRecord");
-        }
-
-        /** Returns the error message: ERR_NOTSUPPORTED */
+        /** throws ERR_NOTSUPPORTED */
         @Override
-        public void createRecord(DBRecord rec, boolean deferredInit)
+        public void createRecord(DBRecord rec, Object[] initalKey, boolean deferredInit)
         {
             throw new NotSupportedException(this, "addRecord");
         }
 
-        /** Returns the error message: ERR_NOTSUPPORTED */
+        /** throws ERR_NOTSUPPORTED */
         @Override
         public void readRecord(DBRecord rec, Object[] keys)
         {
             throw new NotSupportedException(this, "getRecord");
         }
 
-        /** Returns the error message: ERR_NOTSUPPORTED */
+        /** throws ERR_NOTSUPPORTED */
         @Override
         public void updateRecord(DBRecord rec)
         {
             throw new NotSupportedException(this, "updateRecord");
         }
 
-        /** Returns the error message: ERR_NOTSUPPORTED */
+        /** throws ERR_NOTSUPPORTED */
         @Override
         public void deleteRecord(Object[] keys, DBContext context)
         {
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
index 4c1771a..5480f39 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
@@ -337,34 +337,6 @@ public class DBQuery extends DBRowSet
             buf.append(alias);
         }
     }
-
-    /**
-     * Initialize specified DBRecord object with primary key
-     * columns (the Object[] keyValues).
-     * 
-     * @param rec the Record object
-     * @param keyValues an array of the primary key columns
-     */
-    @Override
-    public void initRecord(DBRecord rec, Object[] keyValues, boolean insert)
-    {
-        // Prepare
-        prepareInitRecord(rec, keyValues, insert);
-        // Initialize all Fields
-        Object[] fields = rec.getFields();
-        for (int i = 0; i < fields.length; i++)
-            fields[i] = ObjectUtils.NO_VALUE;
-        // Set primary key values
-        if (keyValues != null)
-        { // search for primary key fields
-            DBColumn[] keyColumns = getKeyColumns();
-            for (int i = 0; i < keyColumns.length; i++)
-                if (columns.contains(keyColumns[i]))
-                    fields[columns.indexOf(keyColumns[i])] = keyValues[i];
-        }
-        // Init
-        completeInitRecord(rec);
-    }
     
     /**
      * Returns an error, because it is not possible to add a record to a query.
@@ -374,7 +346,7 @@ public class DBQuery extends DBRowSet
      * @throws NotImplementedException because this is not implemented
      */
     @Override
-    public void createRecord(DBRecord rec, boolean deferredInit)
+    public void createRecord(DBRecord rec, Object[] initalKey, boolean deferredInit)
     {
         throw new NotImplementedException(this, "createRecord");
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
index 652740d..c6e86a8 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
@@ -883,13 +883,11 @@ public class DBRecord extends DBRecordData implements DBContextAware, Record, Cl
     }
 
     /**
-     * Initializes this record object 
-     * @param key the record key
-     * @param insert if true the record will be in the state NEW otherwise the state will be VALID
+     * Creates a new record
      */
-    public void init(Object[] key, boolean insert)
-    {   // Init with keys
-        rowset.initRecord(this, key, insert);
+    public void create(Object[] initalKey)
+    {
+        rowset.createRecord(this, initalKey, true);
     }
 
     /**
@@ -897,7 +895,7 @@ public class DBRecord extends DBRecordData implements DBContextAware, Record, Cl
      */
     public void create()
     {
-        rowset.createRecord(this, false);
+        rowset.createRecord(this, null, false);
     }
     
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index bd8f6c7..2d1a5c5 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -232,7 +232,7 @@ public abstract class DBRowSet extends DBExpr
     
     public abstract boolean isUpdateable();
 
-    public abstract void createRecord(DBRecord rec, boolean deferredInit);
+    public abstract void createRecord(DBRecord rec, Object[] initalKey, boolean deferredInit);
 
     public abstract void deleteRecord(Object[] keys, DBContext context);
     
@@ -507,23 +507,6 @@ public abstract class DBRowSet extends DBExpr
     {
         return columns.get(index);
     }
-    
-    /**
-     * Initialize this DBRowSet object and sets it's initial state.
-     * 
-     * @param rec the DBRecord object to initialize this DBRowSet object
-     * @param rowSetData any further RowSet specific data
-     * @param insert
-     */
-    protected void prepareInitRecord(DBRecord rec, Object rowSetData, boolean insert)
-    {
-        if (rec==null || rec.getRowSet()!=this)
-            throw new InvalidArgumentException("rec", rec);
-        if (columns.size() < 1)
-            throw new ObjectNotValidException(this);
-        // Init
-        rec.initData(rowSetData, insert);
-    }
 
     /**
      * Initializes a DBRecord for this RowSet and sets primary key values (the Object[] keyValues).
@@ -532,10 +515,10 @@ public abstract class DBRowSet extends DBExpr
      * @param rec the Record object
      * @param keyValues an array of the primary key columns
      */
-    public void initRecord(DBRecord rec, Object[] keyValues, boolean insert)
+    protected void initRecord(DBRecord rec, Object[] keyValues, Connection conn, boolean setDefaults, boolean newRecord)
     {
         // Prepare
-        prepareInitRecord(rec, null, insert);
+        prepareInitRecord(rec, null, newRecord);
         // Initialize all Fields
         Object[] fields = rec.getFields();
         /* 
@@ -553,7 +536,10 @@ public abstract class DBRowSet extends DBExpr
             }
         }
         // Set defaults (don't provide connection here)
-        initRecordDefaultValues(rec, null);
+        if (setDefaults)
+        {
+            initRecordDefaultValues(rec, conn);
+        }
         // Init
         completeInitRecord(rec);
     }
@@ -608,11 +594,37 @@ public abstract class DBRowSet extends DBExpr
      */
     protected void initRecordDefaultValues(DBRecord rec, Connection conn)
     {
-        /* 
-         * Implemented in DBTable
+        /**
+         * Overridden in DBTable
          * 
-         * Not useful for Views and Queries
+         * Set to NO_VALUE for Views and Queries
          */
+        Object[] fields = rec.getFields();
+        // Set Default values
+        for (int i = 0; i < fields.length; i++)
+        {   // already set ?
+            if (fields[i]!=null)
+                continue; 
+            // check default
+            fields[i] = ObjectUtils.NO_VALUE;
+        }
+    }
+    
+    /**
+     * Initialize this DBRowSet object and sets it's initial state.
+     * 
+     * @param rec the DBRecord object to initialize this DBRowSet object
+     * @param rowSetData any further RowSet specific data
+     * @param insert
+     */
+    protected void prepareInitRecord(DBRecord rec, Object rowSetData, boolean newRecord)
+    {
+        if (rec==null || rec.getRowSet()!=this)
+            throw new InvalidArgumentException("rec", rec);
+        if (columns.size() < 1)
+            throw new ObjectNotValidException(this);
+        // Init
+        rec.initData(rowSetData, newRecord);
     }
     
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index 46f24d4..4bbd2aa 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -566,22 +566,10 @@ public class DBTable extends DBRowSet implements Cloneable
      * @param conn a valid connection to the database.
      */
     @Override
-    public void createRecord(DBRecord rec, boolean deferredInit)
+    public void createRecord(DBRecord rec, Object[] initalKey, boolean deferredInit)
     {
-        // Prepare
-        prepareInitRecord(rec, null, true);
-        // Set Defaults
         Connection conn = (deferredInit ? null : rec.getContext().getConnection());
-        int count = columns.size();
-        for (int i = 0; i < count; i++)
-        {
-            DBTableColumn column = (DBTableColumn)columns.get(i);
-            Object value = column.getRecordDefaultValue(conn);
-            if (value!=null)
-                rec.modifyValue(i, value, true); 
-        }
-        // Init
-        completeInitRecord(rec);
+        super.initRecord(rec, initalKey, conn, true, true);
     }
     
     /**
@@ -750,6 +738,7 @@ public class DBTable extends DBRowSet implements Cloneable
         }
         */
         // Set Default values
+        // ATTENTION: Do not set to ObjectUtils.NO_VALUE
         for (int i = 0; i < fields.length; i++)
         {   // already set ?
             if (fields[i]!=null)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBView.java b/empire-db/src/main/java/org/apache/empire/db/DBView.java
index fa9ec5b..1dfca41 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBView.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBView.java
@@ -410,7 +410,7 @@ public abstract class DBView extends DBRowSet
      * @see org.apache.empire.db.DBRowSet#addRecord(org.apache.empire.db.DBRecord, java.sql.Connection)
      */
     @Override
-    public void createRecord(DBRecord rec, boolean deferredInit)
+    public void createRecord(DBRecord rec, Object[] initalKey, boolean deferredInit)
     {
         throw new NotSupportedException(this, "createRecord");
     }
diff --git a/empire-db/src/test/java/org/apache/empire/db/SerializeTest.java b/empire-db/src/test/java/org/apache/empire/db/SerializeTest.java
index 8bf990f..7c731ba 100644
--- a/empire-db/src/test/java/org/apache/empire/db/SerializeTest.java
+++ b/empire-db/src/test/java/org/apache/empire/db/SerializeTest.java
@@ -67,7 +67,7 @@ public class SerializeTest
         db.open(context);
         
         DBRecord rec1Original = new DBRecord(context, db.T_TEST);
-        rec1Original.init(DBRecord.key(1), true);
+        rec1Original.create(DBRecord.key(1));
         DBRecord rec1Serial = ClassUtils.testSerialization(DBRecord.class, rec1Original);
         
         Assert.assertTrue(rec1Serial.isValid());
@@ -89,7 +89,7 @@ public class SerializeTest
         db.open(context);
         
         DBRecord rec2Original = new SerializableRecord(context, db.T_TEST);
-        rec2Original.init(DBRecord.key(1), true);
+        rec2Original.create(DBRecord.key(1));
         DBRecord rec2Serial = ClassUtils.testSerialization(DBRecord.class, rec2Original);
 
         Assert.assertTrue(rec2Serial.isValid());
diff --git a/empire-db/src/test/java/org/apache/empire/dbms/hsql/DBMSHandlerHSqlTest.java b/empire-db/src/test/java/org/apache/empire/dbms/hsql/DBMSHandlerHSqlTest.java
index 809973c..9398c04 100644
--- a/empire-db/src/test/java/org/apache/empire/dbms/hsql/DBMSHandlerHSqlTest.java
+++ b/empire-db/src/test/java/org/apache/empire/dbms/hsql/DBMSHandlerHSqlTest.java
@@ -20,6 +20,7 @@ package org.apache.empire.dbms.hsql;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.sql.Connection;
@@ -73,6 +74,7 @@ public class DBMSHandlerHSqlTest{
         
         DBRecord emp = new DBRecord(context, db.EMPLOYEE);
         emp.create();
+        assertNotNull("Employee-ID is null", emp.getValue(db.EMPLOYEE.ID));
         emp.setValue(db.EMPLOYEE.FIRSTNAME, "junit");
         emp.setValue(db.EMPLOYEE.LASTNAME, "test");
         emp.setValue(db.EMPLOYEE.GENDER, "m");
@@ -80,7 +82,8 @@ public class DBMSHandlerHSqlTest{
         emp.update();
         
         DBRecord emp2 = new DBRecord(context, db.EMPLOYEE);
-        emp2.init(null, true);
+        emp2.create(null);
+        assertNull("Employee-ID is NOT null", emp2.getValue(db.EMPLOYEE.ID));
         emp2.setValue(db.EMPLOYEE.FIRSTNAME, "junit2");
         emp2.setValue(db.EMPLOYEE.LASTNAME, "test2");
         emp2.setValue(db.EMPLOYEE.GENDER, "m");