Skip to content

Instantly share code, notes, and snippets.

@robertoschwald
Created February 19, 2016 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertoschwald/f6b248134938b78e0979 to your computer and use it in GitHub Desktop.
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
/*
* 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