diff --git a/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.MySQLInnoDBDialect/sample.sql b/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.MySQLInnoDBDialect/sample.sql deleted file mode 100644 index ec41ade051..0000000000 --- a/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.MySQLInnoDBDialect/sample.sql +++ /dev/null @@ -1,4 +0,0 @@ --- --- Insert post-creation scripts here --- This is specific to the dialect described in the path to the file --- \ No newline at end of file diff --git a/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.Oracle9Dialect/post-create-indexes.sql b/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.Oracle9Dialect/post-create-indexes.sql index 826399ad97..373194f988 100644 --- a/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.Oracle9Dialect/post-create-indexes.sql +++ b/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.Oracle9Dialect/post-create-indexes.sql @@ -16,6 +16,12 @@ CREATE INDEX FKE1A550BCA8FC7769 ON alf_node_assoc (target_node_id); CREATE INDEX FK71C2002B7F2C8017 ON alf_node_status (node_id); CREATE INDEX FKBD4FF53D22DBA5BA ON alf_store (root_node_id); +-- +-- Transaction tables +-- +CREATE INDEX FK71C2002B9E57C13D ON alf_node_status (transaction_id); +CREATE INDEX FKB8761A3A9AE340B7 ON alf_transaction (server_id); + -- -- New audit tables -- diff --git a/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.SQLServerDialect/post-create-indexes.sql b/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.SQLServerDialect/post-create-indexes.sql new file mode 100644 index 0000000000..1a385c5260 --- /dev/null +++ b/config/alfresco/dbscripts/create/1.4/org.hibernate.dialect.SQLServerDialect/post-create-indexes.sql @@ -0,0 +1,30 @@ +-- +-- Add post-creation indexes. (SQL Server Schema 1.4) +-- +CREATE INDEX FKFFF41F9960601995 ON alf_access_control_entry (permission_id); +CREATE INDEX FKFFF41F99B25A50BF ON alf_access_control_entry (authority_id); +CREATE INDEX FKFFF41F99B9553F6C ON alf_access_control_entry (acl_id); +CREATE INDEX FK8A749A657B7FDE43 ON alf_auth_ext_keys (id); +CREATE INDEX FKFFC5468E74173FF4 ON alf_child_assoc (child_node_id); +CREATE INDEX FKFFC5468E8E50E582 ON alf_child_assoc (parent_node_id); +CREATE INDEX FK60EFB626B9553F6C ON alf_node (acl_id); +CREATE INDEX FK60EFB626D24ADD25 ON alf_node (protocol, identifier); +CREATE INDEX FK7D4CF8EC7F2C8017 ON alf_node_properties (node_id); +CREATE INDEX FKD654E027F2C8017 ON alf_node_aspects (node_id); +CREATE INDEX FKE1A550BCB69C43F3 ON alf_node_assoc (source_node_id); +CREATE INDEX FKE1A550BCA8FC7769 ON alf_node_assoc (target_node_id); +CREATE INDEX FK71C2002B7F2C8017 ON alf_node_status (node_id); +CREATE INDEX FKBD4FF53D22DBA5BA ON alf_store (root_node_id); + +-- +-- Transaction tables +-- +CREATE INDEX FK71C2002B9E57C13D ON alf_node_status (transaction_id); +CREATE INDEX FKB8761A3A9AE340B7 ON alf_transaction (server_id); + +-- +-- New audit tables +-- +CREATE INDEX FKEAD1817484342E39 ON alf_audit_fact (audit_date_id); +CREATE INDEX FKEAD18174A0F9B8D9 ON alf_audit_fact (audit_source_id); +CREATE INDEX FKEAD18174F524CFD7 ON alf_audit_fact (audit_conf_id); diff --git a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-1.sql b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-1.sql index 9b14fec91c..350604fc57 100644 --- a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-1.sql +++ b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-1.sql @@ -1,5 +1,5 @@ -- ------------------------------------------------------ --- Alfresco Schema conversion V1.3 to V1.4 Part 1 +-- Alfresco Schema conversion V1.3 to V1.4 Part 1 (MySQL) -- -- Adds the columns required to enforce the duplicate name detection -- @@ -25,6 +25,11 @@ DROP TABLE IF EXISTS T_permission; DROP TABLE IF EXISTS T_store; DROP TABLE IF EXISTS T_version_count; +-- +-- Upgrades to 1.3 of MyIsam tables could have missed the applied_patch table InnoDB +-- +ALTER TABLE applied_patch ENGINE = InnoDB; + -- -- Unique name constraint -- @@ -47,20 +52,70 @@ ALTER TABLE node_assoc -- -- Rename tables to give 'alf_' prefix -- -ALTER TABLE access_control_entry RENAME TO alf_access_control_entry; -ALTER TABLE access_control_list RENAME TO alf_access_control_list; -ALTER TABLE applied_patch RENAME TO alf_applied_patch; -ALTER TABLE auth_ext_keys RENAME TO alf_auth_ext_keys; -ALTER TABLE authority RENAME TO alf_authority; -ALTER TABLE child_assoc RENAME TO alf_child_assoc; -ALTER TABLE node RENAME TO alf_node; -ALTER TABLE node_aspects RENAME TO alf_node_aspects; -ALTER TABLE node_assoc RENAME TO alf_node_assoc; -ALTER TABLE node_properties RENAME TO alf_node_properties; -ALTER TABLE node_status RENAME TO alf_node_status; -ALTER TABLE permission RENAME TO alf_permission; -ALTER TABLE store RENAME TO alf_store; -ALTER TABLE version_count RENAME TO alf_version_count; +ALTER TABLE access_control_entry RENAME TO alf_access_control_entry; +ALTER TABLE access_control_list RENAME TO alf_access_control_list; +ALTER TABLE applied_patch RENAME TO alf_applied_patch; +ALTER TABLE auth_ext_keys RENAME TO alf_auth_ext_keys; +ALTER TABLE authority RENAME TO alf_authority; +ALTER TABLE child_assoc RENAME TO alf_child_assoc; +ALTER TABLE node RENAME TO alf_node; +ALTER TABLE node_aspects RENAME TO alf_node_aspects; +ALTER TABLE node_assoc RENAME TO alf_node_assoc; +ALTER TABLE node_properties RENAME TO alf_node_properties; +ALTER TABLE node_status RENAME TO alf_node_status; +ALTER TABLE permission RENAME TO alf_permission; +ALTER TABLE store RENAME TO alf_store; +ALTER TABLE version_count RENAME TO alf_version_count; + +-- +-- The table renames will cause Hibernate to rehash the FK constraint names. +-- For MySQL, Hibernate will generate scripts to add the appropriate constraints +-- and indexes. +-- +ALTER TABLE alf_access_control_entry + DROP FOREIGN KEY FKF064DF7560601995, + DROP INDEX FKF064DF7560601995, + DROP FOREIGN KEY FKF064DF75B25A50BF, + DROP INDEX FKF064DF75B25A50BF, + DROP FOREIGN KEY FKF064DF75B9553F6C, + DROP INDEX FKF064DF75B9553F6C; +ALTER TABLE alf_auth_ext_keys + DROP FOREIGN KEY FK31D3BA097B7FDE43, + DROP INDEX FK31D3BA097B7FDE43; +ALTER TABLE alf_child_assoc + DROP FOREIGN KEY FKC6EFFF3274173FF4, + DROP INDEX FKC6EFFF3274173FF4, + DROP FOREIGN KEY FKC6EFFF328E50E582, + DROP INDEX FKC6EFFF328E50E582;(optional) +ALTER TABLE alf_child_assoc + DROP FOREIGN KEY FKFFC5468E74173FF4, + DROP INDEX FKFFC5468E74173FF4, + DROP FOREIGN KEY FKFFC5468E8E50E582, + DROP INDEX FKFFC5468E8E50E582;(optional) +ALTER TABLE alf_node + DROP FOREIGN KEY FK33AE02B9553F6C, + DROP INDEX FK33AE02B9553F6C; +ALTER TABLE alf_node + DROP FOREIGN KEY FK33AE02D24ADD25, + DROP INDEX FK33AE02D24ADD25; +ALTER TABLE alf_node_properties + DROP FOREIGN KEY FKC962BF907F2C8017, + DROP INDEX FKC962BF907F2C8017; +ALTER TABLE alf_node_aspects + DROP FOREIGN KEY FK2B91A9DE7F2C8017, + DROP INDEX FK2B91A9DE7F2C8017; +ALTER TABLE alf_node_assoc + DROP FOREIGN KEY FK5BAEF398B69C43F3, + DROP INDEX FK5BAEF398B69C43F3; +ALTER TABLE alf_node_assoc + DROP FOREIGN KEY FK5BAEF398A8FC7769, + DROP INDEX FK5BAEF398A8FC7769; +ALTER TABLE alf_node_status + DROP FOREIGN KEY FK38ECB8CF7F2C8017, + DROP INDEX FK38ECB8CF7F2C8017; +ALTER TABLE alf_store + DROP FOREIGN KEY FK68AF8E122DBA5BA, + DROP INDEX FK68AF8E122DBA5BA; -- -- Record script finish diff --git a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-2.sql b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-2.sql index 9a3c77833f..84f27b9117 100644 --- a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-2.sql +++ b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-1.4-2.sql @@ -1,5 +1,5 @@ -- ------------------------------------------------------ --- Alfresco Schema conversion V1.3 to V1.4 Part 2 +-- Alfresco Schema conversion V1.3 to V1.4 Part 2 (MySQL) -- -- Adds the alf_transaction and alf_server tables to keep track of the sources -- of transactions. @@ -25,7 +25,6 @@ CREATE TABLE alf_transaction ( change_txn_id varchar(56) NOT NULL, PRIMARY KEY (id), KEY FKB8761A3A9AE340B7 (server_id), - KEY IDX_CHANGE_TXN (change_txn_id), CONSTRAINT FKB8761A3A9AE340B7 FOREIGN KEY (server_id) REFERENCES alf_server (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into alf_transaction @@ -44,7 +43,8 @@ UPDATE alf_node_status ns SET ns.transaction_id = ); ALTER TABLE alf_node_status DROP COLUMN change_txn_id, - ADD CONSTRAINT FK71C2002B9E57C13D FOREIGN KEY (transaction_id) REFERENCES alf_transaction (id); + ADD CONSTRAINT FK71C2002B9E57C13D FOREIGN KEY (transaction_id) REFERENCES alf_transaction (id), + ADD INDEX FK71C2002B9E57C13D (transaction_id); -- -- Record script finish diff --git a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql index e5cfb444c1..89e82d22d6 100644 --- a/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql +++ b/config/alfresco/dbscripts/upgrade/1.4/org.hibernate.dialect.Oracle9Dialect/AlfrescoSchemaUpdate-1.4-2.sql @@ -27,7 +27,6 @@ create table alf_transaction change_txn_id varchar2(56 char) not null, primary key (id) ); -create index CHANGE_TXN_ID on alf_transaction (change_txn_id); alter table alf_transaction add constraint FKB8761A3A9AE340B7 foreign key (server_id) references alf_server; create index FKB8761A3A9AE340B7 on alf_transaction (server_id); diff --git a/config/alfresco/extension/custom-db-connection.properties.sample b/config/alfresco/extension/custom-db-connection.properties.sample index 175328c81f..de46bd2233 100644 --- a/config/alfresco/extension/custom-db-connection.properties.sample +++ b/config/alfresco/extension/custom-db-connection.properties.sample @@ -9,7 +9,13 @@ #db.pool.max=100 # -# MySQL connection (This is default and requires mysql-connector-java-3.1.12-bin.jar, which ships with the Alfresco server) +# HSQL connection +# +#db.driver=org.hsqldb.jdbcDriver +#db.url=jdbc:hsqldb:file:alf_data/hsql_data/alfresco;ifexists=true;shutdown=true; + +# +# MySQL connection (This is default and requires mysql-connector-java-5.0.3-bin.jar, which ships with the Alfresco server) # #db.driver=org.gjt.mm.mysql.Driver #db.url=jdbc:mysql://localhost/alfresco diff --git a/config/alfresco/extension/custom-hibernate-dialect.properties.sample b/config/alfresco/extension/custom-hibernate-dialect.properties.sample index 611a40ca78..e3563689d5 100644 --- a/config/alfresco/extension/custom-hibernate-dialect.properties.sample +++ b/config/alfresco/extension/custom-hibernate-dialect.properties.sample @@ -7,6 +7,11 @@ # For a full list: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#configuration-optional-dialects # +# +# HSQL dialect +# +#hibernate.dialect=org.hibernate.dialect.HSQLDialect + # # MySQL dialect (default) # diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 76e1aeaa53..aad05f496d 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -96,6 +96,6 @@ patch.schemaUpgradeScript.description=Ensures that the database upgrade script h patch.schemaUpgradeScript.err.not_executed=The schema upgrade script, ''{0}'', has not been run against this database. patch.uniqueChildName.description=Checks and renames duplicate children. -patch.uniqueChildName.copyOf=({0}) +patch.uniqueChildName.copyOf=({0}-{1}) patch.uniqueChildName.result=Checked {0} associations and fixed {1} duplicates. See file {2} for details. - +patch.uniqueChildName.err.unable_to_fix=Auto-fixing of duplicate names failed. See file {0} for details. diff --git a/config/alfresco/messages/schema-update.properties b/config/alfresco/messages/schema-update.properties index f927e17562..425124efa3 100644 --- a/config/alfresco/messages/schema-update.properties +++ b/config/alfresco/messages/schema-update.properties @@ -1,6 +1,7 @@ # Schema update messages schema.update.msg.executing_script=Executing database script: {0} +schema.update.msg.optional_statement_failed=Optional statement execution failed:\n SQL: {0}\n Error: {1}\n File: {2}\n Line: {3} schema.update.err.statement_failed=Statement execution failed:\n SQL: {0}\n Error: {1}\n File: {2}\n Line: {3} schema.update.err.update_failed=Schema auto-update failed schema.update.err.validation_failed=Schema validation failed diff --git a/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java b/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java index 28a77aadd3..4fde56eac5 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; +import java.util.Collection; import java.util.Date; import java.util.List; @@ -30,6 +31,7 @@ import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.domain.ChildAssoc; import org.alfresco.repo.domain.Node; import org.alfresco.repo.node.db.NodeDaoService; +import org.alfresco.service.cmr.admin.PatchException; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -51,6 +53,7 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class UniqueChildNamePatch extends AbstractPatch { private static final String MSG_SUCCESS = "patch.uniqueChildName.result"; + private static final String ERR_UNABLE_TO_FIX = "patch.uniqueChildName.err.unable_to_fix"; private static final String MSG_COPY_OF = "patch.uniqueChildName.copyOf"; /** the number of associations to process at a time */ private static final int MAX_RESULTS = 1000; @@ -143,6 +146,7 @@ public class UniqueChildNamePatch extends AbstractPatch @SuppressWarnings("unused") List assocTypeQNames = getUsedAssocQNames(); + boolean unableToFix = false; int fixed = 0; int processed = 0; // check loop through all associations, looking for duplicates @@ -185,8 +189,10 @@ public class UniqueChildNamePatch extends AbstractPatch String usedChildName = childName; processed++; boolean duplicate = false; + int duplicateNumber = 0; while(true) { + duplicateNumber++; try { // push the name back to the node @@ -195,11 +201,46 @@ public class UniqueChildNamePatch extends AbstractPatch } catch (DuplicateChildNodeNameException e) { - // there was a duplicate, so adjust the name and change the node property - duplicate = true; - // assign a new name - usedChildName = childName + I18NUtil.getMessage(MSG_COPY_OF, processed); - // try again + if (duplicateNumber == 10) + { + // Try removing the secondary parent associations + writeLine(" Removing secondary parents of node " + childNode.getId()); + Collection parentAssocs = childNode.getParentAssocs(); + for (ChildAssoc parentAssoc : parentAssocs) + { + if (!parentAssoc.getIsPrimary()) + { + write(" - ").writeLine(parentAssoc); + // remove it + getSession().delete(parentAssoc); + } + } + // flush to ensure the database gets the changes + getSession().flush(); + // try again to be sure + continue; + } + else if (duplicateNumber > 10) + { + // after 10 attempts, we have to admit defeat. Perhaps there is a larger issue. + Collection parentAssocs = childNode.getParentAssocs(); + write(" Unable to set child name '" + usedChildName + "' for node " + childNode.getId()); + writeLine(" with parent associations:"); + for (ChildAssoc parentAssoc : parentAssocs) + { + write(" - ").writeLine(parentAssoc); + } + duplicate = false; + unableToFix = true; + break; + } + else + { + // there was a duplicate, so adjust the name and change the node property + duplicate = true; + // assign a new name + usedChildName = childName + I18NUtil.getMessage(MSG_COPY_OF, processed, duplicateNumber); + } } } // if duplicated, report it @@ -209,11 +250,11 @@ public class UniqueChildNamePatch extends AbstractPatch // get the node path NodeRef parentNodeRef = childAssoc.getParent().getNodeRef(); Path path = nodeService.getPath(parentNodeRef); - writeLine(" Changed duplicated child name:"); - writeLine(" Parent: " + parentNodeRef); - writeLine(" Parent path: " + path); - writeLine(" Duplicate name: " + childName); - writeLine(" Replaced with: " + usedChildName); + writeLine(" Changed duplicated child name:"); + writeLine(" Parent: " + parentNodeRef); + writeLine(" Parent path: " + path); + writeLine(" Duplicate name: " + childName); + writeLine(" Replaced with: " + usedChildName); } } // clear the session to preserve memory @@ -222,10 +263,17 @@ public class UniqueChildNamePatch extends AbstractPatch } } - - // build the result message - String msg = I18NUtil.getMessage(MSG_SUCCESS, processed, fixed, logFile); - return msg; + // check if it was successful or not + if (unableToFix) + { + throw new PatchException(ERR_UNABLE_TO_FIX, logFile); + } + else + { + // build the result message + String msg = I18NUtil.getMessage(MSG_SUCCESS, processed, fixed, logFile); + return msg; + } } @SuppressWarnings("unchecked") diff --git a/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java b/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java index 4a830a42f1..679588c6ca 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/ChildAssocImpl.java @@ -25,7 +25,6 @@ import org.alfresco.repo.domain.ChildAssoc; import org.alfresco.repo.domain.Node; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; /** * @author Derek Hulley @@ -124,9 +123,12 @@ public class ChildAssocImpl implements ChildAssoc, Serializable { StringBuffer sb = new StringBuffer(32); sb.append("ChildAssoc") - .append("[ parent=").append(parent) - .append(", child=").append(child) + .append("[ id=").append(id) + .append(", parent=").append(parent.getId()) + .append(", child=").append(child.getId()) + .append(", child name=").append(childNodeName) .append(", child name crc=").append(childNodeNameCrc) + .append(", assoc type=").append(getTypeQName()) .append(", assoc name=").append(getQname()) .append(", isPrimary=").append(isPrimary) .append("]"); diff --git a/source/java/org/alfresco/repo/domain/hibernate/Transaction.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Transaction.hbm.xml index 46e95aef57..a3c9bad0c9 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Transaction.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Transaction.hbm.xml @@ -29,7 +29,7 @@ unique="false" not-null="false" cascade="none" /> - +