protected void bindCompositeIdentifierToManyToOne()

in grails-datastore-gorm-hibernate/src/main/groovy/org/grails/orm/hibernate/cfg/GrailsDomainBinder.java [2376:2433]


    protected void bindCompositeIdentifierToManyToOne(Association property,
                                                      SimpleValue value, CompositeIdentity compositeId, PersistentEntity refDomainClass,
                                                      String path, String sessionFactoryBeanName) {

        NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);

        String[] propertyNames = compositeId.getPropertyNames();
        PropertyConfig config = getPropertyConfig(property);

        List<ColumnConfig> columns = config.getColumns();
        int i = columns.size();
        int expectedForeignKeyColumnLength = calculateForeignKeyColumnCount(refDomainClass, propertyNames);
        if (i != expectedForeignKeyColumnLength) {
            int j = 0;
            for (String propertyName : propertyNames) {
                ColumnConfig cc;
                // if a column configuration exists in the mapping use it
                if(j < i) {
                    cc = columns.get(j++);
                }
                // otherwise create a new one to represent the composite column
                else {
                    cc = new ColumnConfig();
                }
                // if the name is null then configure the name by convention
                if(cc.getName() == null) {
                    // use the referenced table name as a prefix
                    String prefix = getTableName(refDomainClass, sessionFactoryBeanName);
                    PersistentProperty referencedProperty = refDomainClass.getPropertyByName(propertyName);

                    // if the referenced property is a ToOne and it has a composite id
                    // then a column is needed for each property that forms the composite id
                    if(referencedProperty instanceof ToOne) {
                        ToOne toOne = (ToOne) referencedProperty;
                        PersistentProperty[] compositeIdentity = toOne.getAssociatedEntity().getCompositeIdentity();
                        if(compositeIdentity != null) {
                            for (PersistentProperty cip : compositeIdentity) {
                                // for each property of a composite id by default we use the table name and the property name as a prefix
                                String compositeIdPrefix = addUnderscore(prefix, namingStrategy.propertyToColumnName(referencedProperty.getName()));
                                String suffix = getDefaultColumnName(cip, sessionFactoryBeanName);
                                String finalColumnName = addUnderscore(compositeIdPrefix, suffix);
                                cc = new ColumnConfig();
                                cc.setName(finalColumnName);
                                columns.add(cc);
                            }
                            continue;
                        }
                    }

                    String suffix = getDefaultColumnName(referencedProperty, sessionFactoryBeanName);
                    String finalColumnName = addUnderscore(prefix, suffix);
                    cc.setName(finalColumnName);
                    columns.add(cc);
                }
            }
        }
        bindSimpleValue(property, value, path, config, sessionFactoryBeanName);
    }