persistence@glassfish.java.net

Re: Code changes relevant to Issue 272 : java2db support for UniqueConstraint

From: Pramod Gopinath <Pramod.Gopinath_at_Sun.COM>
Date: Wed, 15 Mar 2006 13:39:24 -0800

Hi Tom/Gordon
  Any updates on my code changes.

Thanks
Pramod

Pramod Gopinath wrote:
> Hi Gordon/Tom
> These are the changes for issue 272 : Support in java2db for
> UniqueConstraints
>
> Problems with the existing code:
> 1. As per the spec the user could provide multiple @UniqueConstraint
> annotations for an entity. But the original code was taking the fields
> that were part of the unique constraint and storing them into a Vector
> in DatabaseTable. This leads to problems at ddl generation type as
> there is no way to know which fields belong to which unique constraint.
>
> 2. Additionally the existing code was taking each of the field names
> that are passed in as part of the UniqueConstraint and creating a
> DatabaseField before setting it into the vector. This is not required.
> We could take the String[] of columns associated to the
> UniqueConstraint and set that as is into the DatabaseTable.
>
> I need help with making changes into this file :
> src/java/oracle/toplink/essentials/internal/ejb/cmp3/xml/EntityMappingsXMLProcessor.java
>
> Could U take a look at the method processUniqueConstraints() in this
> file.
>
>
> Files Added :
> src/java/oracle/toplink/essentials/tools/schemaframework/UniqueKeyConstraint.java
>
>
>
> Files Modified :
> src/java/oracle/toplink/essentials/internal/annotations/EJBAnnotationsProcessor.java
>
> src/java/oracle/toplink/essentials/internal/databaseaccess/DatabasePlatform.java
>
> src/java/oracle/toplink/essentials/internal/helper/DatabaseTable.java
> src/java/oracle/toplink/essentials/tools/schemaframework/DefaultTableGenerator.java
>
> src/java/oracle/toplink/essentials/tools/schemaframework/SchemaManager.java
>
> src/java/oracle/toplink/essentials/tools/schemaframework/TableDefinition.java
>
>
>
> Thanks
> Pramod
> ------------------------------------------------------------------------
>
> cvs server: I know nothing about src/java/oracle/toplink/essentials/tools/schemaframework/UniqueKeyConstraint.java
>
> 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.4
> diff -r1.4 DefaultTableGenerator.java
> 367a368
>
>> tblDef.setUniqueKeys(dbTbl.getUniqueConstraints());
>>
> 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.8
> diff -r1.8 SchemaManager.java
> 141a142
>
>> tableDefinition.setCreateSQLFiles(createSQLFiles);
>>
> 383a385
>
>> tableDefinition.setCreateSQLFiles(createSQLFiles);
>>
> 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.2
> diff -r1.2 TableDefinition.java
> 38a39
>
>> protected Vector uniqueKeys;
>>
> 40a42
>
>> private boolean createSQLFiles;
>>
> 44a47
>
>> this.uniqueKeys = new Vector();
>>
> 105a109,117
>
>> public void addUniqueKeyConstraint(String name, String sourceField) {
>> UniqueKeyConstraint uniqueKey = new UniqueKeyConstraint(name, sourceField);
>> addUniqueKeyConstraint(uniqueKey);
>> }
>>
>> /**
>> * PUBLIC:
>> * Add a foreign key constraint to the table.
>> */
>>
> 109c121,129
> <
> ---
>
>>
>> /**
>> * PUBLIC:
>> * Add a foreign key constraint to the table.
>> */
>> public void addUniqueKeyConstraint(UniqueKeyConstraint uniqueKey) {
>> getUniqueKeys().addElement(uniqueKey);
>> }
>>
>>
> 200a221,257
>
>> * Return the alter table statement to add the constraints.
>> * This is done seperatly from the create because of dependecies.
>> */
>> public Writer buildUniqueConstraintCreationWriter(AbstractSession session, UniqueKeyConstraint uniqueKey, Writer writer) throws ValidationException {
>> try {
>> writer.write("ALTER TABLE " + getFullName());
>> writer.write(" ADD CONSTRAINT ");
>> if (!session.getPlatform().shouldPrintConstraintNameAfter()) {
>> writer.write(uniqueKey.getName() + " ");
>> }
>> uniqueKey.appendDBString(writer, session);
>> if (session.getPlatform().shouldPrintConstraintNameAfter()) {
>> writer.write(" CONSTRAINT " + uniqueKey.getName());
>> }
>> } catch (IOException ioException) {
>> throw ValidationException.fileError(ioException);
>> }
>> return writer;
>> }
>>
>> /**
>> * INTERNAL:
>> * Return the alter table statement to drop the constraints.
>> * This is done seperatly to allow constraints to be dropped before the tables.
>> */
>> public Writer buildUniqueConstraintDeletionWriter(AbstractSession session, UniqueKeyConstraint uniqueKey, Writer writer) throws ValidationException {
>> try {
>> writer.write("ALTER TABLE " + getFullName());
>> writer.write(session.getPlatform().getConstraintDeletionString() + uniqueKey.getName());
>> } catch (IOException ioException) {
>> throw ValidationException.fileError(ioException);
>> }
>> return writer;
>> }
>>
>> /**
>> * INTERNAL:
>>
> 295c352,353
> < Vector foreignKeysClone = (Vector)getForeignKeys().clone();
> ---
>
>> DatabaseField dbField = null;
>> Vector foreignKeysClone = (Vector)getForeignKeys().clone();
>>
> 316a375,390
>
>>
>> Vector uniqueKeysClone = (Vector)getUniqueKeys().clone();
>> setUniqueKeys(new Vector());
>>
>> Object[] uniqueKeysArray = uniqueKeysClone.toArray();
>> UniqueKeyConstraint uniqueKeyConstraint = new UniqueKeyConstraint();
>> int serialNumber = 0;
>> for (Object uniqueKeys : uniqueKeysArray) {
>> uniqueKeyConstraint = buildUniqueKeyConstraint(this, serialNumber++, session.getPlatform());
>> String[] columnNames = (String[])uniqueKeys;
>> for (String columnName : columnNames) {
>> uniqueKeyConstraint.addSourceField(columnName);
>> }
>> addUniqueKeyConstraint(uniqueKeyConstraint);
>> }
>>
>>
> 370a445,482
>
>> protected UniqueKeyConstraint buildUniqueKeyConstraint(TableDefinition table, int serialNumber, DatabasePlatform platform) {
>> UniqueKeyConstraint unqConstraint = new UniqueKeyConstraint();
>> String tempName = buildUniqueKeyConstraintName(table.getName(), serialNumber, platform.getMaxUniqueKeyNameSize());
>> unqConstraint.setName(tempName);
>> return unqConstraint;
>> }
>>
>> /**
>> * Return foreign 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 "FK_" 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) {
>> String uniqueKeyName = "UNQ_" + tableName + "_" + serialNumber;
>> if (uniqueKeyName.length() > maximumNameLength) {
>> // First Remove the "UNQ_" prefix.
>> uniqueKeyName = tableName;
>> if (uniqueKeyName.length() > maximumNameLength) {
>> // 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());
>> }
>> }
>> }
>> }
>> return uniqueKeyName;
>> }
>>
>>
> 386a499,501
>
>> if (uniqueKeys != null) {
>> clone.setUniqueKeys((Vector)uniqueKeys.clone());
>> }
>>
> 394c509
> < public void createConstraints(AbstractSession session, Writer schemaWriter) throws TopLinkException {
> ---
>
>> public void createConstraints(AbstractSession session, Writer schemaWriter) throws TopLinkException {
>>
> 403c518,520
> < schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
> ---
>
>> if (createSQLFiles){
>> schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
>> }
>>
> 408a526,540
>
>>
>> for (Enumeration uniqueKeysEnum = getUniqueKeys().elements();
>> uniqueKeysEnum.hasMoreElements();) {
>> UniqueKeyConstraint uniqueKey = (UniqueKeyConstraint)uniqueKeysEnum.nextElement();
>> buildUniqueConstraintCreationWriter(session, uniqueKey, schemaWriter).toString();
>> try {
>> if (createSQLFiles) {
>> schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
>> }
>> schemaWriter.write("\n");
>> } catch (IOException exception) {
>> throw ValidationException.fileError(exception);
>> }
>> }
>>
>>
> 425a558,568
>
>>
>> if ((!session.getPlatform().supportsUniqueKeyConstraints()) || getUniqueKeys().isEmpty()) {
>> return;
>> }
>>
>> for (Enumeration uniqueKeysEnum = getUniqueKeys().elements();
>> uniqueKeysEnum.hasMoreElements();) {
>> UniqueKeyConstraint uniqueKey = (UniqueKeyConstraint)uniqueKeysEnum.nextElement();
>> session.executeNonSelectingCall(new oracle.toplink.essentials.queryframework.SQLCall(buildUniqueConstraintCreationWriter(session, uniqueKey, new StringWriter()).toString()));
>> }
>>
>>
> 449c592,608
> < schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
> ---
>
>> if (createSQLFiles) {
>> schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
>> }
>> schemaWriter.write("\n");
>> } catch (IOException exception) {
>> throw ValidationException.fileError(exception);
>> }
>> }
>>
>> for (Enumeration uniqueKeysEnum = getUniqueKeys().elements();
>> uniqueKeysEnum.hasMoreElements();) {
>> UniqueKeyConstraint uniqueKey = (UniqueKeyConstraint)uniqueKeysEnum.nextElement();
>> buildUniqueConstraintDeletionWriter(session, uniqueKey, schemaWriter).toString();
>> try {
>> if (createSQLFiles) {
>> schemaWriter.write(session.getPlatform().getStoredProcedureTerminationToken());
>> }
>>
> 475a635,642
>
>> for (Enumeration uniqueKeysEnum = getUniqueKeys().elements();
>> uniqueKeysEnum.hasMoreElements();) {
>> UniqueKeyConstraint uniqueKey = (UniqueKeyConstraint)uniqueKeysEnum.nextElement();
>> try {
>> session.executeNonSelectingCall(new oracle.toplink.essentials.queryframework.SQLCall(buildUniqueConstraintDeletionWriter(session, uniqueKey, new StringWriter()).toString()));
>> } catch (DatabaseException ex) {/* ignore */
>> }
>> }
>>
> 485a653,656
>
>> public Vector getUniqueKeys() {
>> return uniqueKeys;
>> }
>>
>>
> 504a676,683
>
>>
>> public void setUniqueKeys(Vector uniqueKeys) {
>> this.uniqueKeys = uniqueKeys;
>> }
>>
>> public void setCreateSQLFiles(boolean genFlag) {
>> this.createSQLFiles = genFlag;
>> }
>>
> Index: src/java/oracle/toplink/essentials/internal/annotations/EJBAnnotationsProcessor.java
> ===================================================================
> RCS file: /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/annotations/EJBAnnotationsProcessor.java,v
> retrieving revision 1.21
> diff -r1.21 EJBAnnotationsProcessor.java
> 1743,1746c1743
> <
> < for (String columnName : columnNames) {
> < table.addUniqueConstraint(new DatabaseField(columnName));
> < }
> ---
>
>> table.addUniqueConstraint(columnNames);
>>
> 1758c1755
> <
> ---
>
> Index: src/java/oracle/toplink/essentials/internal/databaseaccess/DatabasePlatform.java
> ===================================================================
> RCS file: /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/databaseaccess/DatabasePlatform.java,v
> retrieving revision 1.7
> diff -r1.7 DatabasePlatform.java
> 693a694,702
>
>> * returns the maximum number of characters that can be used in a unique key
>> * name on this platform.
>> */
>> public int getMaxUniqueKeyNameSize() {
>> return getMaxFieldNameSize();
>> }
>>
>> /**
>> * INTERNAL:
>>
> 1249a1259,1262
>
>> return true;
>> }
>>
>> public boolean supportsUniqueKeyConstraints() {
>>
> Index: src/java/oracle/toplink/essentials/internal/ejb/cmp3/xml/EntityMappingsXMLProcessor.java
> ===================================================================
> RCS file: /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/ejb/cmp3/xml/EntityMappingsXMLProcessor.java,v
> retrieving revision 1.20
> diff -r1.20 EntityMappingsXMLProcessor.java
> 2489a2490
>
>> /*
>>
> 2492a2494,2501
>
>> */
>> /* Need to achieve this
>> for (UniqueConstraint uniqueConstraint : (UniqueConstraint[]) constraints) {
>> // UniqueConstraint.columnNames()
>> String[] columnNames = uniqueConstraint.columnNames();
>> table.addUniqueConstraint(columnNames);
>> }
>> */
>>
> 2524c2533
> <
> ---
>
> Index: src/java/oracle/toplink/essentials/internal/helper/DatabaseTable.java
> ===================================================================
> RCS file: /cvs/glassfish/entity-persistence/src/java/oracle/toplink/essentials/internal/helper/DatabaseTable.java,v
> retrieving revision 1.1.1.1
> diff -r1.1.1.1 DatabaseTable.java
> 66,67c66,67
> < public void addUniqueConstraint(DatabaseField uniqueConstraint) {
> < uniqueConstraints.add(uniqueConstraint);
> ---
>
>> public void addUniqueConstraint(String[] columnNames) {
>> uniqueConstraints.add(columnNames);