In Grails if we create a domain class with association we will get a
foreign key for the association. Let’s see how the foreign key gets
named using an example using a many-to-one association.
Here is a simple domain class with an association to itself.
It looks like Grails does not offer any GORM DSL sugar to customize the name of the foreign key. But naming it manually on each domain class may be a bit cumbersome anyway. It would be nice if we could make it use the
Here is a version in groovy implementing the format given above:
It is not perfect. We do not check the length of the generated name and there are are probably other details I do not know anything about yet we have to take care of. But it it a start. :-)
The create table now look like this:
What is left is to activate the code which is a one liner, we just have to add a
Here is a simple domain class with an association to itself.
package gorm
class Category {
Category child
}
The create table
for this class will look like this: CREATE TABLE category (
id bigint NOT NULL,
version bigint NOT NULL,
child_id bigint,
CONSTRAINT category_pkey PRIMARY KEY (id),
CONSTRAINT fk302bcfeabee40a7 FOREIGN KEY (child_id)
REFERENCES category (id)
)
We can see that the primary key gets a human readable name category_pkey
but the name of the foreign key is fk302bcfeabee40a7
. Not too readable. It would be nice if we could give the foreign key a human readable name too. What about <COLUMN>_<TARGET_TABLE>_fkey
to make it similar to the name of the primary key?It looks like Grails does not offer any GORM DSL sugar to customize the name of the foreign key. But naming it manually on each domain class may be a bit cumbersome anyway. It would be nice if we could make it use the
<COLUMN>__<TARGET_TABLE>_fkey
format automatically.Here is a version in groovy implementing the format given above:
package com.pritom import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration import org.hibernate.mapping.PersistentClass import org.hibernate.mapping.ForeignKey /** * Created with IntelliJ IDEA. * User: pritom * Date: 21/10/13 * Time: 10:41 AM * To change this template use File | Settings | File Templates. */ class GormConfiguration extends GrailsAnnotationConfiguration { boolean renamedForeignKeys = false @Override protected void secondPassCompile() { super.secondPassCompile() if (renamedForeignKeys) { return } renameForeignKeys() renamedForeignKeys = true } void renameForeignKeys() { classes.values().each { PersistentClass persistentClass -> persistentClass.table.foreignKeyIterator.each { ForeignKey key -> key.name = createHumanReadableName(key) } } } String createHumanReadableName(ForeignKey key) { "${key.columns.first().name}__${key.referencedTable.name}_fkey" } }
The create table now look like this:
CREATE TABLE category (
id bigint NOT NULL,
version bigint NOT NULL,
child_id bigint,
CONSTRAINT category_pkey PRIMARY KEY (id),
CONSTRAINT child_id__category_fkey FOREIGN KEY (child_id)
REFERENCES category (id)
)
With a nicely named foreign key. :-)What is left is to activate the code which is a one liner, we just have to add a
configClass
parameter to the datasource configuration:dataSource { configClass = com.pritom.GormConfiguration driverClassName = "com.mysql.jdbc.Driver" dbCreate = "create" url = "jdbc:mysql://localhost/grails_db" username = "
grails
" password = "
grails
" }