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 2019/07/09 10:37:33 UTC

[empire-db] branch master updated: EMPIREDB-291: intoducing TIMESTAMP datatype for automatically setting the update_timestamp.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b7986f5  EMPIREDB-291: intoducing TIMESTAMP datatype for automatically setting the update_timestamp.
b7986f5 is described below

commit b7986f5b1956f1859f0d466b8d41d710bf6d6245
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Tue Jul 9 12:37:27 2019 +0200

    EMPIREDB-291: intoducing TIMESTAMP datatype for automatically setting the update_timestamp.
---
 .../apache/empire/db/codegen/CodeGenParser.java    | 21 ++++----
 .../apache/empire/db/codegen/WriterService.java    |  1 +
 .../src/main/resources/templates/Table.vm          |  6 ---
 .../empire/samples/db/advanced/SampleAdvDB.java    |  8 +--
 .../org/apache/empire/samples/db/SampleDB.java     |  8 +--
 .../empire-db-example-codegen/generate-config.xml  |  2 +-
 .../empire-db-example-codegen/generate.bat         |  6 +--
 .../samples/cxf/wssample/server/db/SampleDB.java   |  8 +--
 .../apache/empire/jsf2/websample/db/SampleDB.java  | 10 +---
 .../apache/empire/samples/spring/db/SampleDB.java  |  8 +--
 .../apache/empire/spring/example1/SampleDB.java    |  8 +--
 .../struts2/websample/ws/SampleBeanDomain.java     |  4 +-
 .../empire/struts2/websample/db/SampleDB.java      |  8 +--
 .../org/apache/empire/vue/sample/db/SampleDB.java  |  9 +---
 .../empire/jsf2/controls/TextInputControl.java     | 10 ++--
 .../jsf2/pageelements/BeanListPageElement.java     |  2 +-
 .../empire/jsf2/utils/TagEncodingHelper.java       |  1 +
 empire-db-maven-plugin/pom.xml                     |  2 +-
 .../actionsupport/RecordFormActionSupport.java     |  2 +-
 .../struts2/jsp/controls/TextInputControl.java     | 10 ++--
 .../empire/struts2/jsp/tags/FormPartTag.java       |  3 +-
 empire-db/pom.xml                                  |  2 +-
 .../main/java/org/apache/empire/data/DataType.java | 21 +++++---
 .../java/org/apache/empire/db/DBDDLGenerator.java  |  1 +
 .../org/apache/empire/db/DBDatabaseDriver.java     |  5 +-
 .../src/main/java/org/apache/empire/db/DBExpr.java |  1 +
 .../main/java/org/apache/empire/db/DBIndex.java    | 23 +++++++--
 .../main/java/org/apache/empire/db/DBRowSet.java   |  5 +-
 .../main/java/org/apache/empire/db/DBTable.java    | 57 +++++++++++++++++++---
 .../java/org/apache/empire/db/DBTableColumn.java   |  1 +
 .../empire/db/derby/DBDatabaseDriverDerby.java     |  3 +-
 .../apache/empire/db/h2/DBDatabaseDriverH2.java    |  5 +-
 .../empire/db/mysql/DBDatabaseDriverMySQL.java     |  3 +-
 .../empire/db/oracle/DBDatabaseDriverOracle.java   |  1 +
 .../empire/db/oracle/OracleDataDictionnary.java    |  1 +
 .../db/postgresql/DBDatabaseDriverPostgreSQL.java  |  3 +-
 .../empire/db/sqlite/DBDatabaseDriverSQLite.java   |  2 +-
 .../empire/db/sqlserver/DBDatabaseDriverMSSQL.java |  5 +-
 .../empire/db/validation/DBModelChecker.java       |  3 +-
 .../test/java/org/apache/empire/db/CompanyDB.java  | 13 ++---
 .../empire/db/mysql/DBDatabaseDriverMySQLTest.java |  2 +-
 pom.xml                                            |  6 +--
 42 files changed, 167 insertions(+), 133 deletions(-)

diff --git a/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java b/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java
index 4d34be2..44a187c 100644
--- a/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java
+++ b/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java
@@ -293,18 +293,13 @@ public class CodeGenParser {
 		DBColumn[] keys = new DBColumn[pkCols.size()];
 		ResultSet rs = null;
 		try {
-			rs = dbMeta.getColumns(config.getDbCatalog(), config.getDbSchema(),
-					t.getName(), null);
+			rs = dbMeta.getColumns(config.getDbCatalog(), config.getDbSchema(),	t.getName(), null);
 	        int i=0;
 			while (rs.next()) {
-				DBTableColumn c = addColumn(t, rs);
+				DBTableColumn c = addColumn(t, rs, lockColName);
 				// check if it is a KeyColumn
 				if (pkCols.contains(c.getName()))
 					keys[i++] = c;
-				
-				// check if it is the Timestamp/Locking Column
-				if (lockColName!=null && c.getName().equalsIgnoreCase(lockColName))
-					t.setTimestampColumn(c);
 			}
 	        // Check whether all key columns have been set
 	        for (i=0; i<keys.length; i++)
@@ -361,12 +356,20 @@ public class CodeGenParser {
 	 * Adds DBColumn object to the given DBTable. The DBColumn is created from
 	 * the given ResultSet
 	 */
-	private DBTableColumn addColumn(DBTable t, ResultSet rs)
+	private DBTableColumn addColumn(DBTable t, ResultSet rs, String lockColName)
 			throws SQLException {
 		String name = rs.getString("COLUMN_NAME");
 		DataType empireType = getEmpireDataType(rs.getInt("DATA_TYPE"));
 		double colSize = getColumnSize(empireType, rs.getInt("DATA_TYPE"), rs.getInt("COLUMN_SIZE"));
-		
+
+		// Timestamp column
+        if (empireType==DataType.DATETIME && StringUtils.isNotEmpty(lockColName) && name.equalsIgnoreCase(lockColName))
+        {
+            empireType=DataType.TIMESTAMP;
+            colSize=0;
+        }
+
+        // Number column
 		if (empireType==DataType.DECIMAL || empireType==DataType.FLOAT)
 		{	// decimal digits
 			int decimalDig = rs.getInt("DECIMAL_DIGITS");
diff --git a/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/WriterService.java b/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/WriterService.java
index 38a1507..cb1fb1f 100644
--- a/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/WriterService.java
+++ b/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/WriterService.java
@@ -233,6 +233,7 @@ public class WriterService {
 			return String.class;
 		case DATE:
 		case DATETIME:
+        case TIMESTAMP:
 			return Date.class;
 		case CHAR:
 			return String.class;
diff --git a/empire-db-codegen/src/main/resources/templates/Table.vm b/empire-db-codegen/src/main/resources/templates/Table.vm
index e554024..4f8d382 100644
--- a/empire-db-codegen/src/main/resources/templates/Table.vm
+++ b/empire-db-codegen/src/main/resources/templates/Table.vm
@@ -66,12 +66,6 @@ public class $parser.getTableClassName($table.name) extends ${baseTableClassName
 #end
 #end
 
-		// Optimistic locking column
-#if($parser.hasLockingColumn($table) == true)
-		setTimestampColumn(${parser.getColumnName($table.getTimestampColumn())});
-#else
-		/*no locking column specified*/
-#end
 #end
 	}
 #if($nestTables == true)
diff --git a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
index 9c6e358..43a46f1 100644
--- a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
+++ b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
@@ -69,14 +69,12 @@ public class SampleAdvDB extends DBDatabase
             C_NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             C_HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             C_BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
 
             // Primary Key
             setPrimaryKey(C_DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { C_NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(C_UPDATE_TIMESTAMP);
         }
     }
 
@@ -116,14 +114,12 @@ public class SampleAdvDB extends DBDatabase
             C_EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             C_RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
             C_CHECKSUM        = addColumn("CHECKSUM",         DataType.INTEGER,      0, false);
-            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(C_EMPLOYEE_ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { C_FIRSTNAME, C_LASTNAME, C_DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(C_UPDATE_TIMESTAMP);
 
             // Create Options for GENDER column
             Options genders = new Options();
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 bafaa86..5463f35 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
@@ -72,14 +72,12 @@ public class SampleDB extends DBDatabase
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEPARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
@@ -118,14 +116,12 @@ public class SampleDB extends DBDatabase
             EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
             RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
             
             // Create Options for GENDER column
             Options genders = new Options();
diff --git a/empire-db-examples/empire-db-example-codegen/generate-config.xml b/empire-db-examples/empire-db-example-codegen/generate-config.xml
index 76fefcd..e428c4b 100644
--- a/empire-db-examples/empire-db-example-codegen/generate-config.xml
+++ b/empire-db-examples/empire-db-example-codegen/generate-config.xml
@@ -30,7 +30,7 @@
 		<dbCatalog></dbCatalog>
 		<dbSchema></dbSchema>
 		<dbTablePattern></dbTablePattern>
-		<timestampColumn>CREATIONDATE</timestampColumn>
+		<timestampColumn>UPDATE_TIMESTAMP</timestampColumn>
 		
 		<!-- generation options -->
 		<targetFolder>target/generated-sources/java</targetFolder>
diff --git a/empire-db-examples/empire-db-example-codegen/generate.bat b/empire-db-examples/empire-db-example-codegen/generate.bat
index cfc3788..196dc0a 100644
--- a/empire-db-examples/empire-db-example-codegen/generate.bat
+++ b/empire-db-examples/empire-db-example-codegen/generate.bat
@@ -27,9 +27,9 @@ rem Assemble classpath
 :CLASSPATH
 set classpath=%repo%\org\apache\empire-db\empire-db\%empire-db-version%\empire-db-%empire-db-version%.jar
 set classpath=%classpath%;%repo%\org\apache\empire-db\empire-db-codegen\%empire-db-version%\empire-db-codegen-%empire-db-version%.jar
-set classpath=%classpath%;%repo%\org\slf4j\slf4j-api\1.6.1\slf4j-api-1.6.1.jar
-set classpath=%classpath%;%repo%\org\slf4j\slf4j-log4j12\1.6.1\slf4j-log4j12-1.6.1.jar
-set classpath=%classpath%;%repo%\log4j\log4j\1.2.16\log4j-1.2.16.jar
+set classpath=%classpath%;%repo%\org\slf4j\slf4j-api\1.7.26\slf4j-api-1.7.26.jar
+set classpath=%classpath%;%repo%\org\slf4j\slf4j-log4j12\1.7.26\slf4j-log4j12-1.7.26.jar
+set classpath=%classpath%;%repo%\log4j\log4j\1.2.17\log4j-1.2.17.jar
 set classpath=%classpath%;%repo%\commons-beanutils\commons-beanutils\1.8.3\commons-beanutils-1.8.3.jar
 set classpath=%classpath%;%repo%\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar
 set classpath=%classpath%;%repo%\org\apache\velocity\velocity\1.7\velocity-1.7.jar
diff --git a/empire-db-examples/empire-db-example-cxf/src/main/java/org/apache/empire/samples/cxf/wssample/server/db/SampleDB.java b/empire-db-examples/empire-db-example-cxf/src/main/java/org/apache/empire/samples/cxf/wssample/server/db/SampleDB.java
index 5971084..7701120 100644
--- a/empire-db-examples/empire-db-example-cxf/src/main/java/org/apache/empire/samples/cxf/wssample/server/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-cxf/src/main/java/org/apache/empire/samples/cxf/wssample/server/db/SampleDB.java
@@ -65,14 +65,12 @@ public class SampleDB extends DBDatabase
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
@@ -111,14 +109,12 @@ public class SampleDB extends DBDatabase
             EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
             RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
 
             // Create Options for GENDER column
             Options genders = new Options();
diff --git a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDB.java b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDB.java
index 3096e4c..79dd70d 100644
--- a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/db/SampleDB.java
@@ -69,15 +69,12 @@ public class SampleDB extends DBDatabase
             NAME 			= addColumn("NAME", 			DataType.VARCHAR,   80, true);
             HEAD 			= addColumn("HEAD", 			DataType.VARCHAR,   80, false);
             BUSINESS_UNIT 	= addColumn("BUSINESS_UNIT", 	DataType.VARCHAR,    4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,	 0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
-
         }
     }
 
@@ -117,16 +114,13 @@ public class SampleDB extends DBDatabase
             EMAIL 			= addColumn("EMAIL", 			DataType.VARCHAR,	80, false);
             RETIRED			= addColumn("RETIRED", 			DataType.BOOL, 		 0, true, false);
             // PICTURE 		= addColumn("PICTURE", 			DataType.BLOB, 		 0, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,	 0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("PERSON_NAME_IDX", true, new DBColumn[] { FIRST_NAME, LAST_NAME, DATE_OF_BIRTH });
 
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
-
             // Create Options for GENDER column
             Options genders = new Options();
             genders.set("M", "!option.employee.gender.male");
diff --git a/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/samples/spring/db/SampleDB.java b/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/samples/spring/db/SampleDB.java
index 046764d..40277bf 100644
--- a/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/samples/spring/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/samples/spring/db/SampleDB.java
@@ -66,14 +66,12 @@ public class SampleDB extends DBDatabase
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
@@ -112,14 +110,12 @@ public class SampleDB extends DBDatabase
             EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
             RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
 
             // Create Options for GENDER column
             Options genders = new Options();
diff --git a/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java b/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
index c25e501..d13f647 100644
--- a/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
+++ b/empire-db-examples/empire-db-example-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
@@ -67,14 +67,12 @@ public class SampleDB extends DBDatabase
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
@@ -113,14 +111,12 @@ public class SampleDB extends DBDatabase
             EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
             RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
 
             // Create Options for GENDER column
             Options genders = new Options();
diff --git a/empire-db-examples/empire-db-example-struts2-cxf/src/main/java/org/apache/empire/struts2/websample/ws/SampleBeanDomain.java b/empire-db-examples/empire-db-example-struts2-cxf/src/main/java/org/apache/empire/struts2/websample/ws/SampleBeanDomain.java
index 0f27d18..0b6936b 100644
--- a/empire-db-examples/empire-db-example-struts2-cxf/src/main/java/org/apache/empire/struts2/websample/ws/SampleBeanDomain.java
+++ b/empire-db-examples/empire-db-example-struts2-cxf/src/main/java/org/apache/empire/struts2/websample/ws/SampleBeanDomain.java
@@ -52,7 +52,7 @@ public class SampleBeanDomain extends BeanDomain
             C_NAME            = addProp("name",            DataType.VARCHAR,      80, true);
             C_HEAD            = addProp("head",            DataType.VARCHAR,      80, false);
             C_BUSINESS_UNIT   = addProp("businessUnit",    DataType.VARCHAR,       4, true);
-            C_UPDATE_TIMESTAMP= addProp("updateTimestamp", DataType.DATETIME,      0, true, true);
+            C_UPDATE_TIMESTAMP= addProp("updateTimestamp", DataType.TIMESTAMP,     0, true, true);
         
             // Primary Key
             setKeyColumn(C_DEPARTMENT_ID);
@@ -95,7 +95,7 @@ public class SampleBeanDomain extends BeanDomain
             C_PHONE_NUMBER    = addProp("phoneNumber",		DataType.VARCHAR,     40, false, 	"phone");
             C_EMAIL           = addProp("email",            DataType.VARCHAR,     80, false);
             C_RETIRED         = addProp("retired",          DataType.BOOL,         0, true);
-            C_UPDATE_TIMESTAMP= addProp("updateTimestamp",	DataType.DATETIME,     0, true, "    text", true);
+            C_UPDATE_TIMESTAMP= addProp("updateTimestamp",	DataType.TIMESTAMP,    0, true, "    text", true);
         
             // Primary Key
             setKeyColumn(C_EMPLOYEE_ID);
diff --git a/empire-db-examples/empire-db-example-struts2/src/main/java/org/apache/empire/struts2/websample/db/SampleDB.java b/empire-db-examples/empire-db-example-struts2/src/main/java/org/apache/empire/struts2/websample/db/SampleDB.java
index 4ac2a5a..c08cec3 100644
--- a/empire-db-examples/empire-db-example-struts2/src/main/java/org/apache/empire/struts2/websample/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-struts2/src/main/java/org/apache/empire/struts2/websample/db/SampleDB.java
@@ -57,14 +57,12 @@ public class SampleDB extends DBDatabase
             C_NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             C_HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             C_BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
         
             // Primary Key
             setPrimaryKey(C_DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { C_NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(C_UPDATE_TIMESTAMP);
 
         }    
     }   
@@ -102,14 +100,12 @@ public class SampleDB extends DBDatabase
             C_PHONE_NUMBER    = addColumn("PHONE_NUMBER",     DataType.VARCHAR,     40, false);
             C_EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             C_RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            C_UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
         
             // Primary Key
             setPrimaryKey(C_EMPLOYEE_ID);
             // Set other Indexes
             addIndex("PERSON_NAME_IDX", true, new DBColumn[] { C_FIRSTNAME, C_LASTNAME, C_DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(C_UPDATE_TIMESTAMP);
             
             // Create Options for GENDER column
             Options genders = new Options();
diff --git a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
index 5fdfbca..75ebfad 100644
--- a/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
+++ b/empire-db-examples/empire-db-example-vue/src/main/java/org/apache/empire/vue/sample/db/SampleDB.java
@@ -69,14 +69,12 @@ public class SampleDB extends DBDatabase
             NAME 			= addColumn("NAME", 			DataType.VARCHAR,	80, true);
             HEAD 			= addColumn("HEAD", 			DataType.VARCHAR,	80, false);
             BUSINESS_UNIT 	= addColumn("BUSINESS_UNIT", 	DataType.VARCHAR,    4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,  0, true);
 
             // Primary Key
             setPrimaryKey(DEPARTMENT_ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
 
         }
     }
@@ -117,16 +115,13 @@ public class SampleDB extends DBDatabase
             EMAIL 			= addColumn("EMAIL", 			DataType.VARCHAR,	80, false);
             RETIRED			= addColumn("RETIRED", 			DataType.BOOL, 		 0, true, false);
             // PICTURE 		= addColumn("PICTURE", 			DataType.BLOB, 		 0, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,	 0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,  0, true);
 
             // Primary Key
             setPrimaryKey(EMPLOYEE_ID);
             // Set other Indexes
             addIndex("PERSON_NAME_IDX", true, new DBColumn[] { FIRST_NAME, LAST_NAME, DATE_OF_BIRTH });
 
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
-
             // Create Options for GENDER column
             Options genders = new Options();
             genders.set("M", "!option.employee.gender.male");
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
index a6b99e2..bbfbaea 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/controls/TextInputControl.java
@@ -183,7 +183,7 @@ public class TextInputControl extends InputControl
             NumberFormat nf = NumberFormat.getNumberInstance(ii.getLocale());
             return parseNumber(value, nf);
         }
-        if (type == DataType.DATE || type == DataType.DATETIME)
+        if (type == DataType.DATE || type == DataType.DATETIME || type == DataType.TIMESTAMP)
         {
             return parseDate(value, getDateFormat(column.getDataType(), ii, column));
         }
@@ -276,9 +276,9 @@ public class TextInputControl extends InputControl
             NumberFormat nf = getNumberFormat(dataType, vi.getLocale(), column);
             return nf.format(value);
         }
-        if (dataType == DataType.DATE || dataType == DataType.DATETIME)
+        if (dataType == DataType.DATE || dataType == DataType.DATETIME || dataType == DataType.TIMESTAMP)
         { // Date or DateTime
-            if (dataType == DataType.DATETIME && hasFormatOption(vi, "notime"))
+            if (dataType!= DataType.DATE && hasFormatOption(vi, "notime"))
                 dataType = DataType.DATE;
             // Now format the date according to the user's locale
             DateFormat df = getDateFormat(dataType, vi, column);
@@ -446,7 +446,7 @@ public class TextInputControl extends InputControl
             return 1;
         if (type == DataType.DATE)
             return 10;
-        if (type == DataType.DATETIME)
+        if (type == DataType.DATETIME || type == DataType.TIMESTAMP)
             return 16;
         if (type == DataType.CLOB)
             return 0; // unlimited (use 0x7FFFFFFF instead?)
@@ -477,7 +477,7 @@ public class TextInputControl extends InputControl
         }
         if (value instanceof Date)
         { // Check desired type
-            if (desiredType == DataType.DATETIME || desiredType == DataType.DATE)
+            if (desiredType == DataType.DATETIME || desiredType == DataType.DATE || desiredType == DataType.TIMESTAMP)
                 return desiredType;
             // Detect type
             if (value instanceof Timestamp)
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
index 0c60ab6..893fadc 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pageelements/BeanListPageElement.java
@@ -112,7 +112,7 @@ public class BeanListPageElement<T> extends ListPageElement<T> implements ListIt
         {   // Date sort order is descending by default
             if (defaultSortColumn.getRowSet()!=rowset)
                 throw new InvalidArgumentException("defaultSortColumn", defaultSortColumn);
-            if (defaultSortColumn.getDataType() == DataType.DATE || defaultSortColumn.getDataType() == DataType.DATETIME)
+            if (defaultSortColumn.getDataType().isDate())
                 defaultSortAscending = false;
         }
         // Set Bean Class and more
diff --git a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
index 4bfafc8..84434c5 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
@@ -1407,6 +1407,7 @@ public class TagEncodingHelper implements NamingContainer
                 return CSS_DATA_TYPE_TEXT;
             case DATE:
             case DATETIME:
+            case TIMESTAMP:
                 return CSS_DATA_TYPE_DATE;
             case BOOL:
                 return CSS_DATA_TYPE_BOOL;
diff --git a/empire-db-maven-plugin/pom.xml b/empire-db-maven-plugin/pom.xml
index 30cd265..0e39f02 100644
--- a/empire-db-maven-plugin/pom.xml
+++ b/empire-db-maven-plugin/pom.xml
@@ -64,7 +64,7 @@
 		<dependency>
 			<groupId>log4j</groupId>
 			<artifactId>log4j</artifactId>
-			<version>1.2.16</version>
+			<version>1.2.17</version>
 		</dependency>
 		<dependency>
 			<groupId>junit</groupId>
diff --git a/empire-db-struts2/src/main/java/org/apache/empire/struts2/actionsupport/RecordFormActionSupport.java b/empire-db-struts2/src/main/java/org/apache/empire/struts2/actionsupport/RecordFormActionSupport.java
index 38f0f81..b493216 100644
--- a/empire-db-struts2/src/main/java/org/apache/empire/struts2/actionsupport/RecordFormActionSupport.java
+++ b/empire-db-struts2/src/main/java/org/apache/empire/struts2/actionsupport/RecordFormActionSupport.java
@@ -299,7 +299,7 @@ public abstract class RecordFormActionSupport extends FormActionSupport
             }
             else if ((value=action.getRequestParam(field + "!"))!=null)
             {   // hidden value
-                if (col.getDataType()==DataType.DATE || col.getDataType()==DataType.DATETIME)
+                if (col.getDataType().isDate())
                 {   // Special for Dates and timestamps
                     if (value.equals(sysdate)==false)
                     {   // Parse Date Time
diff --git a/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/controls/TextInputControl.java b/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/controls/TextInputControl.java
index a493e07..338c213 100644
--- a/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/controls/TextInputControl.java
+++ b/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/controls/TextInputControl.java
@@ -56,7 +56,7 @@ public class TextInputControl extends InputControl
         if (type==DataType.DECIMAL)
         {   return parseDecimal(value, getNumberFormat(column.getDataType(), locale, column));
         }
-        if (type==DataType.DATE || type==DataType.DATETIME)
+        if (type==DataType.DATE || type==DataType.DATETIME || type==DataType.TIMESTAMP)
         {   return parseDate(value, getDateFormat(column.getDataType(), locale, column));
         }
         if (type==DataType.AUTOINC)
@@ -135,9 +135,9 @@ public class TextInputControl extends InputControl
             NumberFormat nf = getNumberFormat(dataType, vi.getUserLocale(), column);
             return nf.format(value);
         }
-        if (dataType == DataType.DATE || dataType == DataType.DATETIME)
+        if (dataType == DataType.DATE || dataType == DataType.DATETIME || dataType == DataType.TIMESTAMP)
         { // Date or DateTime
-            if (dataType== DataType.DATETIME && hasFormatOption(vi, "notime"))
+            if (dataType!= DataType.DATE && hasFormatOption(vi, "notime"))
                 dataType = DataType.DATE;
             // Now format the date according to the user's locale
             DateFormat df = getDateFormat(dataType, vi.getUserLocale(), column);
@@ -246,7 +246,7 @@ public class TextInputControl extends InputControl
             return 1;
         if (type==DataType.DATE)
             return 10;
-        if (type==DataType.DATETIME)
+        if (type==DataType.DATETIME || type==DataType.TIMESTAMP)
             return 16;
         if (type==DataType.CLOB)
             return 0; // unlimited (use 0x7FFFFFFF instead?)
@@ -274,7 +274,7 @@ public class TextInputControl extends InputControl
         }
         if (value instanceof Date)
         { // Check desired type
-            if (desiredType == DataType.DATETIME || desiredType == DataType.DATE)
+            if (desiredType == DataType.TIMESTAMP || desiredType == DataType.DATETIME || desiredType == DataType.DATE)
                 return desiredType;
             // Detect type
             if (value instanceof Timestamp)
diff --git a/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/tags/FormPartTag.java b/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/tags/FormPartTag.java
index 7618330..5c46529 100644
--- a/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/tags/FormPartTag.java
+++ b/empire-db-struts2/src/main/java/org/apache/empire/struts2/jsp/tags/FormPartTag.java
@@ -271,8 +271,9 @@ public class FormPartTag extends EmpireTagSupport // FormTag
                 if (record.isNull(i))
                     continue;
                 // Add hidden field
+                DataType dataType = column.getDataType();
                 String value = StringUtils.toString(record.getValue(i)); 
-                if (column.getDataType()==DataType.DATETIME && sysdate.equals(value)==false)
+                if ((dataType==DataType.DATETIME || dataType==DataType.TIMESTAMP) && sysdate.equals(value)==false)
                 {   // Special for Timestamps
                     Date date = ObjectUtils.getDate(record.getValue(i));
                     value = formatDate(date, "yyyy-MM-dd HH:mm:ss.S");
diff --git a/empire-db/pom.xml b/empire-db/pom.xml
index 63bd0ee..cb406b6 100644
--- a/empire-db/pom.xml
+++ b/empire-db/pom.xml
@@ -43,7 +43,7 @@
 		<dependency>
 			<groupId>log4j</groupId>
 			<artifactId>log4j</artifactId>
-			<version>1.2.16</version>
+			<version>1.2.17</version>
 			<scope>test</scope>
 		</dependency>
 		<dependency>
diff --git a/empire-db/src/main/java/org/apache/empire/data/DataType.java b/empire-db/src/main/java/org/apache/empire/data/DataType.java
index 9b5c791..bb1eda5 100644
--- a/empire-db/src/main/java/org/apache/empire/data/DataType.java
+++ b/empire-db/src/main/java/org/apache/empire/data/DataType.java
@@ -64,39 +64,44 @@ public enum DataType
     DATETIME, //     = 5;
     
     /**
+     * Automatic Record timestamp (only one per table allowed)  
+     */
+    TIMESTAMP, //    = 6;
+    
+    /**
      * Fixed length character value.
      */
-    CHAR, //         = 6;
+    CHAR, //         = 7;
     
     /**
      * floating point value
      */
-    FLOAT, //        = 7;
+    FLOAT, //        = 8;
     
     /**
      * Decimal numeric value (size indicates scale and precision)
      */
-    DECIMAL, //      = 8;
+    DECIMAL, //      = 9;
     
     /**
      * Boolean field (emulated if not supported by DBMS as number or char)
      */
-    BOOL, //         = 9;
+    BOOL, //         = 10;
     
     /**
      * Long text &gt; 2K
      */
-    CLOB, //         = 10;
+    CLOB, //         = 11;
     
     /**
      * Binary data
      */
-    BLOB, //         = 11;
+    BLOB, //         = 12;
     
     /**
      * Unique Identifier (non-numeric, treated like text) 
      */
-    UNIQUEID; //     = 12;
+    UNIQUEID; //     = 13;
     
     /**
      * Returns true if the data type is a text based data type (char, text or clob)
@@ -122,7 +127,7 @@ public enum DataType
      */
     public boolean isDate()
     {
-        return (this==DataType.DATE || this==DataType.DATETIME);
+        return (this==DataType.DATE || this==DataType.DATETIME || this==DataType.TIMESTAMP);
     }
 
     /**
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java b/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
index 09124be..5de832e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDDLGenerator.java
@@ -125,6 +125,7 @@ public abstract class DBDDLGenerator<T extends DBDatabaseDriver>
                 sql.append(DATATYPE_DATE);
                 break;
             case DATETIME:
+            case TIMESTAMP:
                 sql.append(DATATYPE_TIMESTAMP);
                 break;
             case BOOL:
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java b/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
index a75c5e6..3cdeb2b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabaseDriver.java
@@ -391,7 +391,7 @@ public abstract class DBDatabaseDriver implements Serializable
         {   // emulate using java.util.UUID
             return UUID.randomUUID();
         }
-        else if ((type==DataType.DATE || type==DataType.DATETIME))
+        else if (type==DataType.DATE || type==DataType.DATETIME || type==DataType.TIMESTAMP)
         {   // Get database system's date and time
             Date ts = db.getUpdateTimestamp(conn);
             return (type==DataType.DATE ? DateUtils.getDateOnly(ts) : ts);
@@ -507,7 +507,7 @@ public abstract class DBDatabaseDriver implements Serializable
     public Object getResultValue(ResultSet rset, int columnIndex, DataType dataType)
         throws SQLException
     {
-        if (dataType == DataType.DATETIME)
+        if (dataType == DataType.DATETIME || dataType == DataType.TIMESTAMP)
         { // Get Timestamp (do not use getObject()!) 
             return rset.getTimestamp(columnIndex);
         } 
@@ -721,6 +721,7 @@ public abstract class DBDatabaseDriver implements Serializable
             case DATE:
                 return getSQLDateTimeString(value, SQL_DATE_TEMPLATE, SQL_DATE_PATTERN, SQL_CURRENT_DATE);
             case DATETIME:
+            case TIMESTAMP:
                 // System date is special case
                 if (!DBDatabase.SYSDATE.equals(value) && value.toString().length()<=10)
                     return getSQLDateTimeString(value, SQL_DATE_TEMPLATE, SQL_DATE_PATTERN, SQL_CURRENT_DATETIME);
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
index 8abc46c..56c5c65 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBExpr.java
@@ -139,6 +139,7 @@ public abstract class DBExpr extends DBObject
                 return String.class;
             case DATE:
             case DATETIME:
+            case TIMESTAMP:
                 return Date.class;
             case CHAR:
                 return Character.class;
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBIndex.java b/empire-db/src/main/java/org/apache/empire/db/DBIndex.java
index 862e760..be6a6d9 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBIndex.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBIndex.java
@@ -18,8 +18,6 @@
  */
 package org.apache.empire.db;
 
-import org.apache.empire.exceptions.InvalidArgumentException;
-
 /**
  * This class handles the primary key for the tables.
  * The primary key contains one or more columns.
@@ -83,9 +81,6 @@ public class DBIndex extends DBObject
      */
     void setTable(DBTable table)
     {
-        if (table==null || !table.getIndexes().contains(this))
-            throw new InvalidArgumentException("table", table);
-        // table
         this.table = table;
     }
 
@@ -114,6 +109,24 @@ public class DBIndex extends DBObject
     {
         return columns;
     }
+    
+    /**
+     * checks whether the columns of this index match the supplied columns
+     * @param columns
+     * @return true if columns match or false otherwise
+     */
+    public boolean compareColumns(DBColumn[] columns)
+    {
+        if (columns==null || columns.length!=this.columns.length)
+            return false;
+        // Compare all columns
+        for (int i=0; i<columns.length; i++)
+        {
+            if (!columns[i].equals(this.columns[i]))
+                return false;
+        }
+        return true;
+    }
 
     /**
      * Returns the columnExpressions belonging to this index.
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 0ddd595..505761d 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
@@ -390,14 +390,15 @@ public abstract class DBRowSet extends DBExpr
     {
         return timestampColumn;
     }
+    
     /**
      * @param timestampColumn The timestampColumn to set.
      */
     public void setTimestampColumn(DBColumn timestampColumn)
     {
-        if (timestampColumn.getRowSet()!=this)
+        if (timestampColumn!=null && timestampColumn.getRowSet()!=this)
             throw new InvalidArgumentException("timestampColumn", timestampColumn);
-        if (this.timestampColumn!=null && this.timestampColumn!=timestampColumn)
+        if (timestampColumn!=null && this.timestampColumn!=null && this.timestampColumn!=timestampColumn)
             log.warn("Timestamp column has already been set for rowset {}. Replacing with {}", getName(), timestampColumn.getName());
         if (timestampColumn instanceof DBTableColumn)
             ((DBTableColumn) timestampColumn).setReadOnly(true);
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 e30a356..ebdbb3f 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
@@ -213,6 +213,22 @@ public class DBTable extends DBRowSet implements Cloneable
             throw new ItemExistsException(column.getName());
         // add now
         columns.add(column);
+        // auto-set primary key
+        if (column.getDataType()==DataType.AUTOINC)
+        {   // Automatically set primary key
+            if (this.primaryKey==null)
+                this.setPrimaryKey(column);
+            else
+                log.warn("Table {} already has a Primary-Key! DataType of column {} should be INTEGER.", getName(), column.getName());
+        }
+        // auto-set timestamp column
+        if (column.getDataType()==DataType.TIMESTAMP)
+        {   // Automatically set timestamp column
+            if (timestampColumn==null)
+                this.setTimestampColumn(column);
+            else
+                log.warn("Table {} already has a Timestamp column. DataType of column {} should be DATETIME.", getName(), column.getName());
+        }
     }
     
     /**
@@ -337,16 +353,30 @@ public class DBTable extends DBRowSet implements Cloneable
      */
     public void setPrimaryKey(DBColumn... columns)
     {
-        if (columns==null || columns.length==0)
+        if (columns==null)
             throw new InvalidArgumentException("columns", columns);
         // All columns must belong to this table
         for (int i=0; i<columns.length; i++)
             if (columns[i].getRowSet()!=this)
                 throw new InvalidArgumentException("columns["+String.valueOf(i)+"]", columns[i].getFullName());
+        // Check if already exists
+        if (primaryKey!=null)
+        {   // compare columns
+            if (primaryKey.compareColumns(columns))
+                return; // already set
+            // new key
+            removeIndex(primaryKey);
+        }
         // Set primary Key now
-        primaryKey = new DBIndex(name + "_PK", DBIndex.PRIMARYKEY, columns);
-        indexes.add(primaryKey);
-        primaryKey.setTable(this);
+        if (columns.length>0)
+        {   // create primary key
+            primaryKey = new DBIndex(name + "_PK", DBIndex.PRIMARYKEY, columns);
+            addIndex(primaryKey);
+        }
+        else
+        {   // No primary Key
+            primaryKey = null;
+        }
     }
 
     /**
@@ -393,6 +423,20 @@ public class DBTable extends DBRowSet implements Cloneable
     }
 
     /**
+     * removes an index.
+     * 
+     * @param index the index to remove
+     */
+    public void removeIndex(DBIndex index)
+    {
+        if (index.getTable()!=this || !indexes.contains(index))
+            throw new InvalidArgumentException("index", index);
+        // table
+        indexes.remove(index);
+        index.setTable(null);
+    }
+
+    /**
      * Adds a timestamp column to the table used for optimistic locking.
      * 
      * @param columnName the column name
@@ -401,8 +445,9 @@ public class DBTable extends DBRowSet implements Cloneable
      */
     public DBTableColumn addTimestampColumn(String columnName)
     {
-        DBTableColumn col = addColumn(columnName, DataType.DATETIME, 0, true, DBDatabase.SYSDATE);
-        setTimestampColumn(col);
+        DBTableColumn col = addColumn(columnName, DataType.TIMESTAMP, 0, true, DBDatabase.SYSDATE);
+        if (this.timestampColumn!=col)
+            setTimestampColumn(col);    // make sure, this is the timestamp column, even if another one exists
         return col;
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
index 9d4ad4e..916a413 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTableColumn.java
@@ -360,6 +360,7 @@ public class DBTableColumn extends DBColumn
         {
             case DATE:
             case DATETIME:
+            case TIMESTAMP:
                 // Check whether value is a valid date/time value!
                 if (value!=null && !(value instanceof Date) && !DBDatabase.SYSDATE.equals(value))
                 {   // Parse String
diff --git a/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java b/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
index aee4932..86352f6 100644
--- a/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
+++ b/empire-db/src/main/java/org/apache/empire/db/derby/DBDatabaseDriverDerby.java
@@ -252,7 +252,8 @@ public class DBDatabaseDriverDerby extends DBDatabaseDriver
            case DECIMAL:   return "CAST(? AS DECIMAL)";
            case FLOAT:     return "CAST(? AS DECIMAL)";
            case DATE:      return "CAST(? AS DATE)";
-           case DATETIME:  return "CAST(? AS TIMESTAMP)";
+           case DATETIME:
+           case TIMESTAMP: return "CAST(? AS TIMESTAMP)";
            // Convert to text
            case TEXT:
            case VARCHAR:
diff --git a/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java b/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
index dfdfb72..09342fd 100644
--- a/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
+++ b/empire-db/src/main/java/org/apache/empire/db/h2/DBDatabaseDriverH2.java
@@ -298,9 +298,10 @@ public class DBDatabaseDriverH2 extends DBDatabaseDriver
            case BOOL:      return "CAST(? AS UNSIGNED)";
            case INTEGER:   return "CAST(? AS SIGNED)";
            case DECIMAL:   return "CAST(? AS DECIMAL)";
-           case FLOAT:    return "CAST(? AS DECIMAL)";
+           case FLOAT:     return "CAST(? AS DECIMAL)";
            case DATE:      return "CAST(? AS DATE)";
-           case DATETIME:  return "CAST(? AS DATETIME)";
+           case DATETIME:
+           case TIMESTAMP: return "CAST(? AS DATETIME)";
            // Convert to text
            case TEXT:
            case VARCHAR:
diff --git a/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java b/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
index 836d7ea..d366632 100644
--- a/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
@@ -1060,7 +1060,8 @@ public class DBDatabaseDriverMySQL extends DBDatabaseDriver
            case DECIMAL:   return "CAST(? AS DECIMAL)";
            case FLOAT:     return "CAST(? AS DECIMAL)";
            case DATE:      return "CAST(? AS DATE)";
-           case DATETIME:  return "CAST(? AS DATETIME)";
+           case DATETIME:
+           case TIMESTAMP: return "CAST(? AS DATETIME)";
            // Convert to text
            case TEXT:
            case VARCHAR:
diff --git a/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java b/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
index 6c00e7a..9161ca4 100644
--- a/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
+++ b/empire-db/src/main/java/org/apache/empire/db/oracle/DBDatabaseDriverOracle.java
@@ -243,6 +243,7 @@ public class DBDatabaseDriverOracle extends DBDatabaseDriver
             // Convert to date
             case DATE:
             case DATETIME:
+            case TIMESTAMP:
                 if (format != null)
                 { // Convert using a format string
                     return "to_date(?, '"+format.toString()+"')";
diff --git a/empire-db/src/main/java/org/apache/empire/db/oracle/OracleDataDictionnary.java b/empire-db/src/main/java/org/apache/empire/db/oracle/OracleDataDictionnary.java
index 753e538..6e95d6d 100644
--- a/empire-db/src/main/java/org/apache/empire/db/oracle/OracleDataDictionnary.java
+++ b/empire-db/src/main/java/org/apache/empire/db/oracle/OracleDataDictionnary.java
@@ -104,6 +104,7 @@ public class OracleDataDictionnary {
         dataTypeMapping.put("NUMBER",   new DataType[] { DataType.DECIMAL, DataType.FLOAT, 
                                                          DataType.INTEGER, DataType.AUTOINC, DataType.BOOL });
         dataTypeMapping.put("DATE",     new DataType[] { DataType.DATE, DataType.DATETIME });
+        dataTypeMapping.put("TIMESTAMP",new DataType[] { DataType.TIMESTAMP });
         dataTypeMapping.put("CLOB",     new DataType[] { DataType.CLOB });
         dataTypeMapping.put("BLOB",     new DataType[] { DataType.BLOB });
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java b/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
index afe811d..0bb4732 100644
--- a/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/postgresql/DBDatabaseDriverPostgreSQL.java
@@ -400,7 +400,8 @@ public class DBDatabaseDriverPostgreSQL extends DBDatabaseDriver
             case DECIMAL:  return "CAST(? AS DECIMAL)";
             case FLOAT:    return "CAST(? AS DOUBLE PRECISION)";
             case DATE:     return "CAST(? AS DATE)";
-            case DATETIME: return "CAST(? AS TIMESTAMP)";
+            case DATETIME:
+            case TIMESTAMP:return "CAST(? AS TIMESTAMP)";
                 // Convert to text
             case TEXT:
             case VARCHAR:  
diff --git a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
index e62935e..2b6c935 100644
--- a/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
+++ b/empire-db/src/main/java/org/apache/empire/db/sqlite/DBDatabaseDriverSQLite.java
@@ -461,7 +461,7 @@ public class DBDatabaseDriverSQLite extends DBDatabaseDriver
     @Override
     public Object getResultValue(ResultSet rset, int columnIndex, DataType dataType) throws SQLException
     {
-        if (dataType == DataType.DATETIME)
+        if (dataType == DataType.DATETIME || dataType == DataType.TIMESTAMP)
         {
             // SQLite does not have a Date type, or any kind of type :(
             String datePattern = getSQLPhrase(SQL_DATETIME_PATTERN);
diff --git a/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java b/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
index 069a0e4..3cf55cb 100644
--- a/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
+++ b/empire-db/src/main/java/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
@@ -368,7 +368,8 @@ public class DBDatabaseDriverMSSQL extends DBDatabaseDriver
            case DECIMAL:   return "convert(decimal, ?)";
            case FLOAT:     return "convert(float, ?)";
            case DATE:      return "convert(date, ?, 111)";
-           case DATETIME:  return isUseDateTime2() ? "convert(datetime2, ?, 121)"
+           case DATETIME:
+           case TIMESTAMP: return isUseDateTime2() ? "convert(datetime2, ?, 121)"
                                                    : "convert(datetime,  ?, 121)";
            // Convert to text
            case TEXT:
@@ -379,7 +380,7 @@ public class DBDatabaseDriverMSSQL extends DBDatabaseDriver
                 if (srcType==DataType.DATE)
                     return "convert(nvarchar, ?, 111)";
                 // Date-Time-Format "YYYY-MM-DD hh.mm.ss"
-                if (srcType==DataType.DATETIME)
+                if (srcType==DataType.DATETIME || srcType==DataType.TIMESTAMP)
                     return "convert(nvarchar, ?, 120)";
                 // other
                 return "convert(nvarchar, ?)";
diff --git a/empire-db/src/main/java/org/apache/empire/db/validation/DBModelChecker.java b/empire-db/src/main/java/org/apache/empire/db/validation/DBModelChecker.java
index e107974..2600d89 100644
--- a/empire-db/src/main/java/org/apache/empire/db/validation/DBModelChecker.java
+++ b/empire-db/src/main/java/org/apache/empire/db/validation/DBModelChecker.java
@@ -355,6 +355,7 @@ public class DBModelChecker
                 break;
             case DATE:
             case DATETIME:
+            case TIMESTAMP:
                 checkDateColumn(column, remoteColumn, handler);
                 break;
             case CHAR:
@@ -443,7 +444,7 @@ public class DBModelChecker
         checkColumnNullable(column, remoteColumn, handler);
 
         // check type
-        if (!(remoteColumn.getDataType() == DataType.DATE || remoteColumn.getDataType() == DataType.DATETIME))
+        if (!remoteColumn.getDataType().isDate())
         {
             handler.columnTypeMismatch(column, remoteColumn.getDataType());
         }
diff --git a/empire-db/src/test/java/org/apache/empire/db/CompanyDB.java b/empire-db/src/test/java/org/apache/empire/db/CompanyDB.java
index 2c369bc..f0b6f4c 100644
--- a/empire-db/src/test/java/org/apache/empire/db/CompanyDB.java
+++ b/empire-db/src/test/java/org/apache/empire/db/CompanyDB.java
@@ -50,13 +50,11 @@ public class CompanyDB extends DBDatabase
             NAME            = addColumn("NAME",             DataType.VARCHAR,      80, true);
             HEAD            = addColumn("HEAD",             DataType.VARCHAR,      80, false);
             BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.VARCHAR,       4, true, "ITTK");
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
             // Primary Key
             setPrimaryKey(ID);
             // Set other Indexes
             addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
@@ -94,14 +92,12 @@ public class CompanyDB extends DBDatabase
             EMAIL           = addColumn("EMAIL",            DataType.VARCHAR,     80, false);
             SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
             RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,    0, true);
 
             // Primary Key
             setPrimaryKey(ID);
             // Set other Indexes
             addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
 
             // Create Options for GENDER column
             Options genders = new Options();
@@ -127,12 +123,9 @@ public class CompanyDB extends DBDatabase
             // ID
             ID              = addColumn("DEPARTMENT_ID",    DataType.AUTOINC,       0, true, "DATA_ID_SEQUENCE");
             DATA            = addColumn("NAME",             DataType.BLOB,          0, true);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
-
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.TIMESTAMP,     0, true);
             // Primary Key
             setPrimaryKey(ID);
-            // Set timestamp column for save updates
-            setTimestampColumn(UPDATE_TIMESTAMP);
         }
     }
 
diff --git a/empire-db/src/test/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQLTest.java b/empire-db/src/test/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQLTest.java
index 0b353dc..029bac2 100644
--- a/empire-db/src/test/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQLTest.java
+++ b/empire-db/src/test/java/org/apache/empire/db/mysql/DBDatabaseDriverMySQLTest.java
@@ -90,7 +90,7 @@ public class DBDatabaseDriverMySQLTest {
         assertEquals("CAST(? AS DATE)", driver.getConvertPhrase(DataType.DATE, null, "test"));
         
         // DATETIME
-        assertEquals("CAST(? AS DATETIME)", driver.getConvertPhrase(DataType.DATETIME, null, null));
+        assertEquals("CAST(? AS DATETIME)", driver.getConvertPhrase(DataType.TIMESTAMP, null, null));
         assertEquals("CAST(? AS DATETIME)", driver.getConvertPhrase(DataType.DATETIME, null, "test"));
         
         // TEXT
diff --git a/pom.xml b/pom.xml
index 3b5aeaf..3673d73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -273,17 +273,17 @@
 			<dependency>
 				<groupId>org.slf4j</groupId>
 				<artifactId>slf4j-api</artifactId>
-				<version>1.6.1</version>
+				<version>1.7.26</version>
 			</dependency>
 			<dependency>
 				<groupId>org.slf4j</groupId>
 				<artifactId>slf4j-log4j12</artifactId>
-				<version>1.6.1</version>
+				<version>1.7.26</version>
 			</dependency>			
 			<dependency>
 				<groupId>org.slf4j</groupId>
 				<artifactId>slf4j-simple</artifactId>
-				<version>1.6.1</version>
+				<version>1.7.26</version>
 			</dependency>
 			<!-- commons -->			
 			<dependency>