protected void bindCollectionWithJoinTable()

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


    protected void bindCollectionWithJoinTable(ToMany property,
                                               InFlightMetadataCollector mappings, Collection collection, PropertyConfig config, String sessionFactoryBeanName) {

        NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);

        SimpleValue element;
        final boolean isBasicCollectionType = property instanceof Basic;
        if (isBasicCollectionType) {
            element = new SimpleValue(metadataBuildingContext, collection.getCollectionTable());
        }
        else {
            // for a normal unidirectional one-to-many we use a join column
            element = new ManyToOne(metadataBuildingContext, collection.getCollectionTable());
            bindUnidirectionalOneToManyInverseValues(property, (ManyToOne) element);
        }
        collection.setInverse(false);

        String columnName;

        final boolean hasJoinColumnMapping = hasJoinColumnMapping(config);
        if (isBasicCollectionType) {
            final Class<?> referencedType = ((Basic)property).getComponentType();
            String className = referencedType.getName();
            final boolean isEnum = referencedType.isEnum();
            if (hasJoinColumnMapping) {
                columnName = config.getJoinTable().getColumn().getName();
            }
            else {
                columnName = isEnum ? namingStrategy.propertyToColumnName(className) :
                        addUnderscore(namingStrategy.propertyToColumnName(property.getName()),
                                namingStrategy.propertyToColumnName(className));
            }

            if (isEnum) {
                bindEnumType(property, referencedType,element,columnName);
            }
            else {

                String typeName = getTypeName(property, config, getMapping(property.getOwner()));
                if (typeName == null) {
                    Type type = mappings.getTypeConfiguration().getBasicTypeRegistry().getRegisteredType(className);
                    if (type != null) {
                        typeName = type.getName();
                    }
                }
                if (typeName == null) {
                    String domainName = property.getOwner().getName();
                    throw new MappingException("Missing type or column for column["+columnName+"] on domain["+domainName+"] referencing["+className+"]");
                }

                bindSimpleValue(typeName, element,true, columnName, mappings);
                if (hasJoinColumnMapping) {
                    bindColumnConfigToColumn(property, getColumnForSimpleValue(element), config.getJoinTable().getColumn());
                }
            }
        } else {
            final PersistentEntity domainClass = property.getAssociatedEntity();

            Mapping m = getMapping(domainClass);
            if (hasCompositeIdentifier(m)) {
                CompositeIdentity ci = (CompositeIdentity) m.getIdentity();
                bindCompositeIdentifierToManyToOne(property, element, ci, domainClass,
                        EMPTY_PATH, sessionFactoryBeanName);
            }
            else {
                if (hasJoinColumnMapping) {
                    columnName = config.getJoinTable().getColumn().getName();
                }
                else {
                    columnName = namingStrategy.propertyToColumnName(NameUtils.decapitalize(domainClass.getName())) + FOREIGN_KEY_SUFFIX;
                }

                bindSimpleValue("long", element,true, columnName, mappings);
            }
        }

        collection.setElement(element);

        bindCollectionForPropertyConfig(collection, config);
    }