2010-02-05 2 views
2

에서 나는 다음과 같은 클래스가 있습니다.이름 바꾸기 복합 외부 키는 GORM

기존 데이터베이스와 작업하려면 Order 테이블에서 생성 된 열의 이름을 cat_name 및 manuf_id로 바꿔야합니다. 이것이 가능한가요, 그렇다면 어떻게 될까요?

답변

2

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

이 DataSource.groovy에 그것을 SRC/자바 클래스를 넣고 등록 :

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

감사합니다, 그러나 그것은을 위해 작동하지 않습니다 나를. 나는 테이블을 떨어 뜨렸고 같은 테이블 이름으로 테이블을 다시 만들었다. – titaniumdecoy

+0

도메인 클래스의 패키지 이름을 "com.foo.bar"에서 바 꾸었습니까? 거기에 어떤 System.out.println() 문을 던져서 무슨 일이 일어나고 있는지 확인하십시오. –

+0

네, 패키지 이름을 변경했습니다. 코드에 구문 오류가 있으면 오류가 발생하지만 println 문은 실행되지 않습니다. 나는 심지어 파일에 글쓰기를 시도했다. 코드가 어떤 이유로 실행되지 않는 것처럼 보입니다. – titaniumdecoy

2

나는 그것을 필요로하는 도메인 클래스를위한 솔루션을 작성 했으므로 언제든지 다시 읽기가 필요하지 않습니다.

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

DataSource.groovy에 그것을 SRC/그루비/내/응용 프로그램/패키지/MyCustomGrailsAnotationConfiguration.groovy에 my.app.package.MyCustomGrailsAnotationConfiguration.groovy 클래스를 넣고 등록 :

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

나는 희망 그것은 당신에게 유용 할 것입니다. 덕분에이 내 문제를 해결

+1

고마워,하지만 더 이상이 프로젝트에서 일하고 있지 않아. 나는 다른 누군가가 이것을 유용하다고 생각할 것이다. – titaniumdecoy

4

도와 @carlosmain (2.0.4를 Grails에) :

http://jira.grails.org/browse/GRAILS-4504?focusedCommentId=64996&page=com.atlassian.jira.plugin.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' 
     } 
}