J'ai écrit une solution pour n'importe quelle classe de domaine qui en a besoin et vous n'avez pas besoin de readapt à chaque fois.
class Catalog {
static mapping = {
id composite:['name', 'manufacturer']
columns {
name column:'cat_name'
manufacturer column:'manuf_id'
}
}
String name
Manufacturer manufacturer
}
class Order {
Catalog catalog
static mapping = {
}
static foreigners = [
catalog : [name : "catalog_name",
manufacturer: "catalog_manufacturer_name"]
]
}
Ceci est la classe de configuration GORM que j'écris pour consommer les étrangers dans la classe de domaine.
package my.app.package
import java.util.Collection;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
class MyCustomGrailsAnotationConfiguration extends GrailsAnnotationConfiguration{
private static final long serialVersionUID = 1;
private boolean _alreadyProcessed=false;
@SuppressWarnings("unchecked")
@Override
protected void secondPassCompile() throws MappingException {
super.secondPassCompile();
if(_alreadyProcessed){
return;
}
classes.values().each{rootClass ->
if(rootClass instanceof RootClass){
def domainClass= null
Boolean hasForeigners=false
try{
domainClass=Class.forName(rootClass.entityName,false,Thread.currentThread().getContextClassLoader())
hasForeigners = domainClass.metaClass.hasProperty(domainClass, 'foreigners')
}catch(Exception e){}
if(domainClass && hasForeigners){
rootClass?.table?.foreignKeyIterator?.each{fKey->
fKey?.columnIterator?.each{column->
domainClass.foreigners?.each{attrName,columns ->
columns.each{columnItmName,columnItmValue->
def exp=attrName+"_"
columnItmName.split("").each{exp+=(it==~/[A-Z]/) ? "_"+it:it}
exp=exp.toLowerCase()+".(id)\$"
//println "Expression:"+exp
if(column.name.matches(exp)){
//println "Match:"+column.name+" changing to "+columnItmValue
column.name=columnItmValue
}
}
}
}
}
}
}
}
_alreadyProcessed = true;
}
}
Mettez la classe my.app.package.MyCustomGrailsAnotationConfiguration.groovy dans src/Groovy/ma/app/paquet/MyCustomGrailsAnotationConfiguration.groovy et l'enregistrer dans DataSource.groovy:
dataSource {
pooled = true
driverClassName = ...
username = ...
password = ...
configClass = my.app.package.MyCustomGrailsAnotationConfiguration
}
J'espère Cela vous sera utile. Merci pour votre aide @carlosmain
Merci pour le code, mais il ne fonctionne pas pour moi. J'ai laissé tomber la table et l'a recréée avec les mêmes noms de table. – titaniumdecoy
Dumb question, vous avez changé le nom du paquet de la classe de domaine de "com.foo.bar" droit? Ajoutez des instructions System.out.println() pour voir ce qui se passe. –
Oui, j'ai changé le nom du paquet. S'il y a une erreur de syntaxe dans le code, il s'encrasse, mais les instructions println ne sont pas exécutées. J'ai même essayé d'écrire dans un fichier. Le code ne semble pas être exécuté pour une raison quelconque. – titaniumdecoy