views:

142

answers:

1

I have the following classes:


class Catalog {
  static mapping = {
    id composite:['name', 'manufacturer']
    columns {
      name column:'cat_name'
      manufacturer column:'manuf_id'
    }
  }
  String name
  Manufacturer manufacturer
}

class Order {
  static mapping = {
    columns {
      // How to rename foreign keys as cat_name, manuf_id?
    }
  }
  Catalog catalog // creates catalog_name, catalog_manufacturer_name
}

Presently, an Order table is generated with the attributes catalog_name and catalog_manufacturer_name (which reference the composite primary keys of the Catalog table).

I need to rename these generated columns to cat_name and manuf_id in the Order table to work with an existing database. Is this possible, and if so, how?

+1  A: 

It's not possible using GORM configuration, but you can do it with a custom Configuration class:

package com.foo.bar;

import java.util.Collection;
import java.util.Iterator;

import org.codehaus.groovy.grails.orm.hibernate.cfg.DefaultGrailsDomainConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;

public class CompositeAwareHibernateConfiguration extends DefaultGrailsDomainConfiguration {

   private static final long serialVersionUID = 1;

   private boolean _alreadyProcessed;

   @SuppressWarnings("unchecked")
   @Override
   protected void secondPassCompile() throws MappingException {
      super.secondPassCompile();

      if (_alreadyProcessed) {
         return;
      }

      for (PersistentClass pc : (Collection<PersistentClass>)classes.values()) {
         if (pc instanceof RootClass) {
            RootClass root = (RootClass)pc;
            if ("com.foo.bar.Order".equals(root.getClassName())) {
               for (Iterator iter = root.getTable().getColumnIterator(); iter.hasNext(); ) {
                  Column column = (Column)iter.next();
                  if ("catalog_name".equals(column.getName())) {
                     column.setName("cat_name");
                  }
                  else if ("catalog_manufacturer_id".equals(column.getName())) {
                     column.setName("manuf_id");
                  }
               }
            }
         }
      }

      _alreadyProcessed = true;
   }
}

Put the class in src/java and register it in DataSource.groovy:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = com.foo.bar.CompositeAwareHibernateConfiguration
}
Burt Beckwith
Thanks for the code, but it's not working for me. I dropped the table and it recreated it with the same table names.
titaniumdecoy
Dumb question, you changed the package name of the domain class from "com.foo.bar" right? Throw in some System.out.println() statements in there to see what's happening.
Burt Beckwith
Yeah, I changed the package name. If there is a syntax error in the code it chokes, but println statements are not executed. I even tried writing to a file. The code does not seem to be getting executed for some reason.
titaniumdecoy
I couldn't get your code to work but I am marking this answer accepted since I am no longer working on the problem. I decided to use Stripes instead of Grails.
titaniumdecoy