Created
February 19, 2016 13:32
-
-
Save robertoschwald/f6b248134938b78e0979 to your computer and use it in GitHub Desktop.
Grails 2.4.x PostgreSQL duplicate primary keys, indexes, unique keys dbm-gorm-diff workaround
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2013-2016 symentis GmbH - All Rights Reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the 'License'); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an 'AS IS' BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/* | |
* Author: Robert Oschwald | |
*/ | |
import groovy.util.logging.Slf4j | |
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration | |
import org.hibernate.MappingException | |
import org.hibernate.mapping.Index | |
import org.hibernate.mapping.Table | |
import org.hibernate.mapping.UniqueKey | |
import org.hibernate.sql.Alias | |
/** | |
* Workaround for Hibernate PrimaryKey / Index / Unique name-collisions (Hibernate Bug?) on PostgreSQL / H2 | |
* with Database-Migration plugin. | |
* Might be fixed in Liquibase 3.5 (see Grails3 database-migration plugin), but for Grails 2.x there is no current fix | |
* This class works around Hibernate name creation by extending the 15-char limit for the types stated above, | |
* and by prepending the table-name to the index / unique index names were applicable. | |
* See https://jira.grails.org/browse/GPDATABASEMIGRATION-164 | |
* See https://jira.grails.org/browse/GPDATABASEMIGRATION-18 | |
* Installation: | |
* Add to DataSource.groovy: | |
* dataSource { | |
* ... | |
* // Workaround for Hibernate Name clashes (Hibernate Bug) on PostgreSQL / H2 | |
* // See https://jira.grails.org/browse/GPDATABASEMIGRATION-164 | |
* // See https://jira.grails.org/browse/GPDATABASEMIGRATION-18 | |
* configClass = your.package.GrailsDomainConfiguration | |
* } | |
*/ | |
@Slf4j | |
class GrailsDomainConfiguration extends GrailsAnnotationConfiguration { | |
@Override | |
protected void secondPassCompile() throws MappingException { | |
super.secondPassCompile() | |
fixNames() | |
} | |
/** | |
* Perform. | |
*/ | |
private void fixNames(){ | |
this.tableMappings.each { Table table -> | |
fixPrimaryKeyNames(table) | |
fixIndexNames(table) | |
fixUniqueKeys(table) | |
} | |
} | |
/** | |
* By default, primary key names are max. 15 characters. | |
* This can cause name collisions if tables start with same 15 characters | |
*/ | |
private static void fixPrimaryKeyNames(Table table) { | |
Alias pkAlias = new Alias(63, 'PK') | |
if (table?.primaryKey?.name){ | |
String org = table.primaryKey.name | |
String updated = pkAlias.toAliasString(table.name) | |
table.primaryKey.name = updated | |
log.info("Updated primary key constraint name from ${org} to ${updated}") | |
} | |
} | |
/** | |
* The default index key names are only 15 characters long, this creates | |
* naming collisions if columns start with the same 15 characters | |
*/ | |
private static void fixIndexNames(Table table) { | |
Alias idxAlias = new Alias(63, '') | |
table.indexIterator.each { Index index -> | |
String org = index.name | |
String updated = idxAlias.toAliasString(table.name + "_" + index.name) | |
index.name = updated | |
log.info("Updated index name from ${org} to ${updated}") | |
} | |
} | |
/** | |
* The default unique key names are only 15 characters long, this creates | |
* naming collisions if columns start with the same 15 characters | |
*/ | |
private static void fixUniqueKeys(Table table) { | |
Alias ukAlias = new Alias(63, '') | |
table.uniqueKeyIterator.each { UniqueKey uniqueKey -> | |
String org = uniqueKey.name | |
String updated = ukAlias.toAliasString(table.name + "_" + uniqueKey.name) | |
uniqueKey.name = updated | |
log.info("Updated unique key from ${org} to ${updated}") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment