سؤال

لدي الفصول التالية:


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
}

في الوقت الحاضر، يتم إنشاء جدول الطلب باستخدام Catalog_name و Catalog_manufacturer_name (الذي الرجوع إلى المفاتيح الأساسية المركبة من جدول الكتالوج).

أحتاج إلى إعادة تسمية هذه الأعمدة التي تم إنشاؤها إلى cat_name و manuf_id في جدول الطلب للعمل مع قاعدة بيانات موجودة. هل هذ ممكن وان كان، فكيف؟

هل كانت مفيدة؟

المحلول

لا يمكن استخدام تكوين Gorm، ولكن يمكنك القيام بذلك باستخدام فئة تكوين مخصصة:

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;
   }
}

ضع الفصل في SRC / Java وتسجيله في DataSource.groovy:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = com.foo.bar.CompositeAwareHibernateConfiguration
}

نصائح أخرى

هذا حل مشكلتي (شاحن 2.0.4):

http://jira.grails.org/browse/grails-4504؟focusedcommentId=64996&page=com.atlassian.jira.supin.system.issuetabpanels:comment-tabpanel#comment-64996.

قضيتي:

class GroupMessage implements Serializable {

    Group group
    Integer messageId

    static mapping = {
        datasources(['ds1'])
        table 't_group_msg'
        version false
        id composite: ['group', 'messageId'], generator: 'assigned'
        group column:'grpid'
        messageId column:'msgid', type:int
    }
}

class GroupMessageDetail implements Serializable {

    GroupMessage groupMessage
    Integer detailId
    String message
    String url

    static mapping = {
        datasources(['ds1'])
        table 't_group_msg_det'
        version false
        id composite: ['groupMessage', 'detailId'], generator: 'assigned'
        columns {
            groupMessage {
                column name: 'grpid'
                column name: 'msgid'
            }
            detailId column:'id', type:int
            message column:'sms'
            url column:'url'
       }
}

لقد اكتب حلا لأي فئة مجال تحتاج إليه ولا تحتاج إلى قراءة في كل مرة.

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"]
  ]
}

هذه هي فئة تكوين Gorm التي أكتبها لاستهلاك الأجانب في فئة المجال.

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;
    }
}

ضع my.app.package.mycustomgrailsanotationcanecome.groovy class في src / groovy / my / app / package / mycustomgrailsanotationconfiguration.groovy وتسجيله في DataSource.groovy:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = my.app.package.MyCustomGrailsAnotationConfiguration
}

آمل أن تكون مفيدة لك. شكرا @ arlosmain لمساعدتكم

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top