persistence@glassfish.java.net

Re: Code Review for Issue 2476 Incorrect ddl generated for 2 UniqueConstraints on same table with MSSql

From: Tom Ware <tom.ware_at_oracle.com>
Date: Thu, 17 May 2007 13:03:15 -0400

ok. Go ahead and check-in.

-Tom

Wonseok Kim wrote:

> Hi Tom,
>
> I couldn't bring up a general test case because when table name is too
> long, it fails even in creating the table and it cannot run on any
> platform due to the platform-dependent maximum length of
> identifier(128 for Derby, 30 for Oracle, right?). The maximum size of
> unique key name(or field name) for SQL Server is set as 22 in platform
> class, but table name can be much longer as you can see in the issue
> description, so this problem could arise.
>
> I tested the modified method by making real non-automated :) unit test
> against the method to confirm the behavior.
>
> To test this kind of problem well, I think either pure unit test or
> mock database platform would be helpful, but there hasn't been such a
> test so far.
>
> Thanks,
> -Wonseok
>
> On 5/17/07, *Tom Ware* <tom.ware_at_oracle.com
> <mailto:tom.ware_at_oracle.com>> wrote:
>
> Hi Wonseok,
>
> The code looks good.
>
> Were you able to recreate the problem on a non SQL Server
> database by
> either making the names really long or by temporarily shortening the
> allowable lengths? If so, do you think this would make a good
> test case?
>
> -Tom
>
> Wonseok Kim wrote:
>
> > Hi Tom,
> >
> > These days I've been really busy on my original job, but I had some
> > time to fix this issue. :-)
> > https://glassfish.dev.java.net/issues/show_bug.cgi?id=2476
> > <https://glassfish.dev.java.net/issues/show_bug.cgi?id=2476>
> >
> > The logic of generating unique constraint key name had problem of
> > truncating sequence number which is appended to table name,
> therefore
> > if the table name is long and there are more than one unique
> > constraints this problem could occur in any database. I fixed this
> > similar to the logic of generating foreign key constraint
> > name(buildForeignKeyConstraintName method).
> >
> > Please see below diff.
> > With this fix there was no failure in the existing entity
> persistence
> > tests and I confirmed that unique constraint names are generated
> > always with sequence number with my local test. But I could not run
> > the test against MS SQL Server because I don't have a machine now
> > where SQL Server is installed.
> >
> > Thanks,
> > -Wonseok
> >
> > Index:
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/DefaultTableGenerator.java
>
> > ===================================================================
> > RCS file:
> >
> /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/tools/schemaframework/DefaultTableGenerator.java,v
>
> > retrieving revision 1.16
> > diff -c -w -r1.16 DefaultTableGenerator.java
> > ***
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/DefaultTableGenerator.java
> > 6 May 2007 02:17:06 -0000 1.16
> > ---
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/DefaultTableGenerator.java
> > 17 May 2007 08:51:01 -0000
> > ***************
> > *** 742,748 ****
> > UniqueKeyConstraint uniqueKeyConstraint;
> > int serialNumber = 0;
> > for (String[] uniqueConstraint : uniqueConstraints) {
> > ! if(uniqueConstraint.length == 0) continue;
> > uniqueKeyConstraint =
> > sourceTableDef.buildUniqueKeyConstraint(uniqueConstraint,
> > serialNumber++, databasePlatform);
> > sourceTableDef.addUniqueKeyConstraint
> (uniqueKeyConstraint);
> > }
> > --- 742,748 ----
> > UniqueKeyConstraint uniqueKeyConstraint;
> > int serialNumber = 0;
> > for (String[] uniqueConstraint : uniqueConstraints) {
> > ! if(uniqueConstraint == null || uniqueConstraint.length
> > == 0) continue;
> > uniqueKeyConstraint =
> > sourceTableDef.buildUniqueKeyConstraint(uniqueConstraint,
> > serialNumber++, databasePlatform);
> >
> sourceTableDef.addUniqueKeyConstraint(uniqueKeyConstraint);
> > }
> > Index:
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/TableDefinition.java
> > ===================================================================
> > RCS file:
> >
> /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/tools/schemaframework/TableDefinition.java,v
> > retrieving revision 1.10
> > diff -c -w -r1.10 TableDefinition.java
> > ***
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/TableDefinition.java
> > 6 May 2007 02:17:06 -0000 1.10
> > ---
> >
> src/java/oracle/toplink/essentials/tools/schemaframework/TableDefinition.java
>
> > 17 May 2007 08:51:01 -0000
> > ***************
> > *** 479,489 ****
> > }
> >
> > /**
> > ! * Return unique key constraint name built from the table and
> > field name with the specified maximum length. To
> > ! * make the name short enough we
> > * 1. Drop the "UNQ_" prefix.
> > * 2. Drop the underscore characters if any.
> > ! * 3. Drop the vowels from the table and field name.
> > * 4. Truncate the table name to zero length if necessary.
> > */
> > protected String buildUniqueKeyConstraintName(String
> tableName,
> > int serialNumber, int maximumNameLength) {
> > --- 479,489 ----
> > }
> >
> > /**
> > ! * Return unique key constraint name built from the table name
> > and sequence
> > ! * number with the specified maximum length. To make the name
> > short enough we
> > * 1. Drop the "UNQ_" prefix.
> > * 2. Drop the underscore characters if any.
> > ! * 3. Drop the vowels from the table name.
> > * 4. Truncate the table name to zero length if necessary.
> > */
> > protected String buildUniqueKeyConstraintName(String
> tableName,
> > int serialNumber, int maximumNameLength) {
> > ***************
> > *** 495,507 ****
> > // Still too long: remove the underscore
> characters
> > uniqueKeyName =
> > Helper.removeAllButAlphaNumericToFit(tableName + serialNumber,
> > maximumNameLength);
> > if (uniqueKeyName.length() > maximumNameLength) {
> > ! // Still too long: remove vowels from the
> table
> > name and field name.
> > String onlyAlphaNumericTableName =
> > Helper.removeAllButAlphaNumericToFit(tableName, 0);
> > ! uniqueKeyName =
> > Helper.shortenStringsByRemovingVowelsToFit
> (onlyAlphaNumericTableName,
> > "", maximumNameLength);
> > if (uniqueKeyName.length () >
> maximumNameLength) {
> > ! // Still too long: remove vowels from the
> > table name and field name and truncate the table name.
> > String shortenedTableName =
> > Helper.removeVowels(onlyAlphaNumericTableName);
> > ! uniqueKeyName =
> > Helper.truncate(shortenedTableName, maximumNameLength -
> > shortenedTableName.length());
> > }
> > }
> > }
> > --- 495,508 ----
> > // Still too long: remove the underscore
> characters
> > uniqueKeyName =
> > Helper.removeAllButAlphaNumericToFit (tableName + serialNumber,
> > maximumNameLength);
> > if (uniqueKeyName.length() > maximumNameLength) {
> > ! // Still too long: remove vowels from the
> table
> > name
> > String onlyAlphaNumericTableName =
> > Helper.removeAllButAlphaNumericToFit(tableName, 0);
> > ! String serialName =
> String.valueOf(serialNumber);
> > ! uniqueKeyName =
> >
> Helper.shortenStringsByRemovingVowelsToFit(onlyAlphaNumericTableName,
> > serialName, maximumNameLength);
> > if (uniqueKeyName.length() >
> maximumNameLength) {
> > ! // Still too long: remove vowels from the
> > table name and truncate the table name.
> > String shortenedTableName =
> > Helper.removeVowels(onlyAlphaNumericTableName);
> > ! uniqueKeyName =
> > Helper.truncate(shortenedTableName, maximumNameLength -
> > serialName.length()) + serialName;
> > }
> > }
> > }
> >
>
>