persistence@glassfish.java.net

Code review for [Issue 1365] DDL generation 'create-tables' doesn't add constraints in SE mode

From: Wonseok Kim <guruwons_at_gmail.com>
Date: Tue, 21 Nov 2006 20:16:26 +0900

Hi Tom,

Please review this fix(attached) of the following issue.
https://glassfish.dev.java.net/issues/show_bug.cgi?id=1365

Summary of this fix:
* Add creating constraints logic to SchemaManager.createDefaultTables()
* Reuse the default TableCreator instance in SchemaManager. If
toplink.ddl-generation.output-mode is 'both' or run in SE mode, same
SchemaManager was called twice for both files and database output. Each call
created repetitively the same default TableCreator which takes time in
initializing - processing all ClassDescriptors.

Tested with entity-persistence-tests and quick look tests.

Here is the diff:
Index:
src/java/oracle/toplink/essentials/tools/schemaframework/SchemaManager.java
===================================================================
RCS file:
/cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/tools/schemaframework/SchemaManager.java,v
retrieving revision 1.12
diff -c -w -r1.12 SchemaManager.java
***
src/java/oracle/toplink/essentials/tools/schemaframework/SchemaManager.java
7 Nov 2006 20:35:26 -0000 1.12
---
src/java/oracle/toplink/essentials/tools/schemaframework/SchemaManager.java
21 Nov 2006 07:13:55 -0000
***************
*** 56,61 ****
--- 56,62 ----
      protected Writer createSchemaWriter;
      protected Writer dropSchemaWriter;
      protected boolean createSQLFiles = true; //if true, schema writer will
add terminator string.
+     protected TableCreator defaultTableCreator;
      public SchemaManager(DatabaseSessionImpl session) {
          this.session = session;
***************
*** 778,805 ****
      }
      /**
      * Create the default table schema for the TopLink project this session
associated with.
      */
      public void createDefaultTables() {
          //Create each table w/o throwing exception and/or exit if some of
them are already existed in the db.
          //If a table is already existed, skip the creation.
-         Iterator tblDefIter = new DefaultTableGenerator(session.getProject
()).generateDefaultTableCreator().getTableDefinitions().iterator();
!         while (tblDefIter.hasNext()) {
!             TableDefinition tblDef = (TableDefinition)tblDefIter.next();
              boolean shouldLogExceptionStackTrace =
getSession().getSessionLog().shouldLogExceptionStackTrace();
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
              try {
                  createObject(tblDef);
                  session.getSessionLog().log(SessionLog.FINEST,
"default_tables_created", tblDef.getFullName());
              } catch (DatabaseException exception) {
                  // Ignore the exception, table already created
                  session.getSessionLog().log(SessionLog.FINEST,
"default_tables_already_existed", tblDef.getFullName());
              } finally {
getSession().getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
              }
-         }
          //create sequence table
          createSequences();
--- 779,840 ----
      }
      /**
+      * Construct the default TableCreator.
+      * If the default TableCreator is already created, just returns it.
+      */
+     protected TableCreator getDefaultTableCreator() {
+         if(defaultTableCreator == null) {
+             defaultTableCreator = new DefaultTableGenerator(
session.getProject()).generateDefaultTableCreator();
+         }
+         return defaultTableCreator;
+     }
+
+     /**
      * Create the default table schema for the TopLink project this session
associated with.
      */
      public void createDefaultTables() {
          //Create each table w/o throwing exception and/or exit if some of
them are already existed in the db.
          //If a table is already existed, skip the creation.
!         TableCreator tableCreator = getDefaultTableCreator();
!         Vector tableDefinitions = tableCreator.getTableDefinitions();
!
          boolean shouldLogExceptionStackTrace =
getSession().getSessionLog().shouldLogExceptionStackTrace();
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
          try {
+             for (Iterator tblDefIter = tableDefinitions.iterator();
tblDefIter.hasNext();) {
+                 TableDefinition tblDef =
(TableDefinition)tblDefIter.next();
+
+                 try {
                      createObject(tblDef);
                      session.getSessionLog().log(SessionLog.FINEST,
"default_tables_created", tblDef.getFullName());
                  } catch (DatabaseException exception) {
                      // Ignore the exception, table already created
                      session.getSessionLog().log(SessionLog.FINEST,
"default_tables_already_existed", tblDef.getFullName());
+                 }
+             }
+
+             // Unique constraints should be generated before foreign key
constraints,
+             // because foreign key constraints can reference unique
constraints
+             for (Iterator tblDefIter = tableDefinitions.iterator();
tblDefIter.hasNext();) {
+                 try {
+
createUniqueConstraints((TableDefinition)tblDefIter.next());
+                 } catch(DatabaseException exception) {
+                     // Ignore the exception
+                 }
+             }
+
+             for (Iterator tblDefIter = tableDefinitions.iterator();
tblDefIter.hasNext();) {
+                 try {
+
createForeignConstraints((TableDefinition)tblDefIter.next());
+                 } catch(DatabaseException exception) {
+                     // Ignore the exception
+                 }
+             }
          } finally {
getSession().getSessionLog().setShouldLogExceptionStackTrace(shouldLogExceptionStackTrace);
          }
          //create sequence table
          createSequences();
***************
*** 813,820 ****
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
          try {
!             DefaultTableGenerator gen = new DefaultTableGenerator(
session.getProject());
!             gen.generateDefaultTableCreator().replaceTables(session,
this);
          } catch (DatabaseException exception) {
              // Ignore error
          } finally {
--- 848,855 ----
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
          try {
!             TableCreator tableCreator = getDefaultTableCreator();
!             tableCreator.replaceTables(session, this);
          } catch (DatabaseException exception) {
              // Ignore error
          } finally {
***************
*** 830,837 ****
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
          try {
!             DefaultTableGenerator gen = new DefaultTableGenerator(
session.getProject());
!             gen.generateDefaultTableCreator().replaceTables(session, this,
keepSequenceTables);
          } catch (DatabaseException exception) {
              // Ignore error
          } finally {
--- 865,872 ----
getSession().getSessionLog().setShouldLogExceptionStackTrace(false);
          try {
!             TableCreator tableCreator = getDefaultTableCreator();
!             tableCreator.replaceTables(session, this, keepSequenceTables);
          } catch (DatabaseException exception) {
              // Ignore error
          } finally {
Thanks,
-Wonseok