2016-12-02 102 views
0
class Tooth { 
    Integer id 
    ToothDisease toothDisease 
    static mapping = { 
    table name: 'AK_TOOTH' 
    id generator: 'sequence', params: [sequence: 'SEQ_AK_TOOTH'] 
    columns{ 
     toothDisease { 
     column: 'FK_AK_TOOTH_ID' 
     column: 'FK_AK_TOOTH_NR_VERSION' 
     } 
    } 
} 
class ToothDisease implements Serializable{ 
    Integer idColumn 
    Integer nrVersion 
    static mapping = { 
    table name: 'AK_TOOTH_DISEASE' 
    idColumn column: 'ID', generator: 'sequence', params: [sequence: 'SEQ_AK_TOOTH_DISEASE'] 
    nrVersion column: 'NR_VERSION', 
    id composite ['idColumn','nrVersion'] 

    int hashCode() { 
    def builder = new HashCodeBuilder() 
    builder.append (idColumn) 
    builder.append (nrVersion) 
    builder.toHashCode() 
    } 

    boolean equals (other) { 
    if (other == null) { 
     return false 
    } 
    def builder = new EqualsBuilder() 
    builder.append (idColumn, other.idColumn) 
    builder.append (nrVersion, other.nrVersion) 
    builder.isEquals() 
    } 
} 

当我尝试bootRun我的应用程序,我得到BeanCreationException:的Grails 3.1.6,休眠4.复合外键

Caused by: org.hibernate.MappingException: Foreign key (FK_1rnajvolkf4rkav5w1hl0l9fk:AK_TOOTH [tooth_disease_id,FK_AK_TOOTH_ID,FK_AK_TOOTH_NR_VERSION,tooth_disease_id_column,tooth_disease_nr_version])) must have same number of columns as the referenced primary key (AK_TOOTH_DISEASE [ID,NR_VERSION]). 

当我删除了齿列映射部分,然后我得到了同样的错误没有那些列

[tooth_disease_id,tooth_disease_id_column,tooth_disease_nr_version]. 

是否有可能像hibernate中显式定义键列和referencedColumnName? 为什么有三列?尤其是tooth_disease_id and tooth_disease_id_column columns。我试图用“PrimaryKey的”名称作为牙齿和“身份证”简单,因为id列复合主键,但这样一来,我有同样的错误

Caused by: org.hibernate.MappingException: Foreign key (FK_1rnajvolkf4rkav5w1hl0l9fk:AK_TOOTH [tooth_disease_id,FK_AK_TOOTH_ID,FK_AK_TOOTH_NR_VERSION,tooth_disease_id_column,tooth_disease_nr_version])) must have same number of columns as the referenced primary key (AK_TOOTH_DISEASE [ID]).But there is only one referenced primary key. 

不幸的是,我没有机会改变模式结构并避免组合键。

回答

0

我发现here从伯特·贝克威思的解决方法。 由于GrailsAnnotationConfiguration被HibernateMappingContextConfiguration.groovy代替我做了他的解决方案的一些变化:

class CompositeForeignKeyConfiguration extends HibernateMappingContextConfiguration { 
    private static final long serialVersionUID = 1 
    private static final String TOOTH_CLASS_NAME = 'com.project.TOOTH' 
    private static final String TOOTH_ID_FK = 'FK_AK_TOOTH_ID' 
    private static final String TOOTH_VERSION_FK = 'FK_AK_TOOTH_NR_VERSION' 

    private boolean _alreadyProcessed 

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

    for (PersistentEntity pc : hibernateMappingContext.getPersistentEntities()) { 
     if (pc.name == TOOTH_CLASS_NAME) { 
     pc.getAssociations().each { Association mp -> 
      if (mp.name == 'toothDisease') { 
      PropertyConfig config = (PropertyConfig) mp.getMapping().getMappedForm() 
      if (config.columns.size() == 1) { 
       config.columns.clear() 
       final ColumnConfig fk1 = new ColumnConfig (name: TOOTH_ID_FK) 
       final ColumnConfig fk2 = new ColumnConfig (name: TOOTH_VERSION_FK) 
       config.columns << fk1 
       config.columns << fk2 
      } 
      } 
     } 
     } 

    } 

    super.secondPassCompile() 
    if (_alreadyProcessed) { 
     return 
    } 
    _alreadyProcessed = true 
    } 
} 
0

我认为这个错误是由你在Tooth的映射中声明FK到ToothDisease的方式引起的。

试试这个:

class Tooth { 
    Integer id 
    ToothDisease toothDisease 

    static mapping = { 
     table name: 'AK_TOOTH' 
     id generator: 'sequence', params: [sequence: 'SEQ_AK_TOOTH'] 
     toothDisease { 
      column name: 'FK_AK_TOOTH_ID' 
      column name: 'FK_AK_TOOTH_NR_VERSION' 
     } 
    } 

} 

class ToothDisease implements Serializable{ 
    Integer idColumn 
    Integer nrVersion 

    static mapping = { 
     table name: 'AK_TOOTH_DISEASE' 
     idColumn column: 'ID', generator: 'sequence', params: [sequence: 'SEQ_AK_TOOTH_DISEASE'] 
     nrVersion column: 'NR_VERSION' 
     id composite: ['idColumn','nrVersion'] 
    } 

    int hashCode() { 
     def builder = new HashCodeBuilder() 
     builder.append (idColumn) 
     builder.append (nrVersion) 
     builder.toHashCode() 
    } 

    boolean equals (other) { 
     if (other == null) { 
      return false 
     } 
     def builder = new EqualsBuilder() 
     builder.append (idColumn, other.idColumn) 
     builder.append (nrVersion, other.nrVersion) 
     builder.isEquals() 
    } 

} 
+0

谢谢你的答案,但它didn't帮助我。与三列外键仍然相同的错误。 –