Example usage for org.hibernate.mapping Collection setElement

List of usage examples for org.hibernate.mapping Collection setElement

Introduction

In this page you can find the example usage for org.hibernate.mapping Collection setElement.

Prototype

public void setElement(Value element) 

Source Link

Usage

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

protected void bindCollectionSecondPass(GrailsDomainClassProperty property, Mappings mappings,
        Map<?, ?> persistentClasses, Collection collection, String sessionFactoryBeanName) {

    PersistentClass associatedClass = null;

    if (LOG.isDebugEnabled())
        LOG.debug("Mapping collection: " + collection.getRole() + " -> "
                + collection.getCollectionTable().getName());

    PropertyConfig propConfig = getPropertyConfig(property);

    if (propConfig != null && StringUtils.hasText(propConfig.getSort())) {
        if (!property.isBidirectional() && property.isOneToMany()) {
            throw new GrailsDomainException("Default sort for associations ["
                    + property.getDomainClass().getName() + "->" + property.getName()
                    + "] are not supported with unidirectional one to many relationships.");
        }/*  w w w.java  2  s  . com*/
        GrailsDomainClass referenced = property.getReferencedDomainClass();
        if (referenced != null) {
            GrailsDomainClassProperty propertyToSortBy = referenced.getPropertyByName(propConfig.getSort());

            String associatedClassName = property.getReferencedDomainClass().getFullName();

            associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
            if (associatedClass != null) {
                collection.setOrderBy(buildOrderByClause(propertyToSortBy.getName(), associatedClass,
                        collection.getRole(), propConfig.getOrder() != null ? propConfig.getOrder() : "asc"));
            }
        }
    }

    // Configure one-to-many
    if (collection.isOneToMany()) {

        GrailsDomainClass referenced = property.getReferencedDomainClass();
        Mapping m = getRootMapping(referenced);
        boolean tablePerSubclass = m != null && !m.getTablePerHierarchy();

        if (referenced != null && !referenced.isRoot() && !tablePerSubclass) {
            Mapping rootMapping = getRootMapping(referenced);
            String discriminatorColumnName = RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME;

            if (rootMapping != null) {
                final ColumnConfig discriminatorColumn = rootMapping.getDiscriminatorColumn();
                if (discriminatorColumn != null) {
                    discriminatorColumnName = discriminatorColumn.getName();
                }
                if (rootMapping.getDiscriminatorMap().get("formula") != null) {
                    discriminatorColumnName = (String) m.getDiscriminatorMap().get("formula");
                }
            }
            //NOTE: this will build the set for the in clause if it has sublcasses
            Set<String> discSet = buildDiscriminatorSet(referenced);
            String inclause = DefaultGroovyMethods.join(discSet, ",");

            collection.setWhere(discriminatorColumnName + " in (" + inclause + ")");
        }

        OneToMany oneToMany = (OneToMany) collection.getElement();
        String associatedClassName = oneToMany.getReferencedEntityName();

        associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
        // if there is no persistent class for the association throw exception
        if (associatedClass == null) {
            throw new MappingException(
                    "Association references unmapped class: " + oneToMany.getReferencedEntityName());
        }

        oneToMany.setAssociatedClass(associatedClass);
        if (shouldBindCollectionWithForeignKey(property)) {
            collection.setCollectionTable(associatedClass.getTable());
        }

        bindCollectionForPropertyConfig(collection, propConfig);
    }

    if (isSorted(property)) {
        collection.setSorted(true);
    }

    // setup the primary key references
    DependantValue key = createPrimaryKeyValue(mappings, property, collection, persistentClasses);

    // link a bidirectional relationship
    if (property.isBidirectional()) {
        GrailsDomainClassProperty otherSide = property.getOtherSide();
        if (otherSide.isManyToOne() && shouldBindCollectionWithForeignKey(property)) {
            linkBidirectionalOneToMany(collection, associatedClass, key, otherSide);
        } else if (property.isManyToMany() || Map.class.isAssignableFrom(property.getType())) {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    } else {
        if (hasJoinKeyMapping(propConfig)) {
            bindSimpleValue("long", key, false, propConfig.getJoinTable().getKey().getName(), mappings);
        } else {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    }
    collection.setKey(key);

    // get cache config
    if (propConfig != null) {
        CacheConfig cacheConfig = propConfig.getCache();
        if (cacheConfig != null) {
            collection.setCacheConcurrencyStrategy(cacheConfig.getUsage());
        }
    }

    // if we have a many-to-many
    if (property.isManyToMany() || isBidirectionalOneToManyMap(property)) {
        GrailsDomainClassProperty otherSide = property.getOtherSide();

        if (property.isBidirectional()) {
            if (LOG.isDebugEnabled())
                LOG.debug("[GrailsDomainBinder] Mapping other side " + otherSide.getDomainClass().getName()
                        + "." + otherSide.getName() + " -> " + collection.getCollectionTable().getName()
                        + " as ManyToOne");
            ManyToOne element = new ManyToOne(mappings, collection.getCollectionTable());
            bindManyToMany(otherSide, element, mappings, sessionFactoryBeanName);
            collection.setElement(element);
            bindCollectionForPropertyConfig(collection, propConfig);
            if (property.isCircular()) {
                collection.setInverse(false);
            }
        } else {
            // TODO support unidirectional many-to-many
        }
    } else if (shouldCollectionBindWithJoinColumn(property)) {
        bindCollectionWithJoinTable(property, mappings, collection, propConfig, sessionFactoryBeanName);

    } else if (isUnidirectionalOneToMany(property)) {
        // for non-inverse one-to-many, with a not-null fk, add a backref!
        // there are problems with list and map mappings and join columns relating to duplicate key constraints
        // TODO change this when HHH-1268 is resolved
        bindUnidirectionalOneToMany(property, mappings, collection);
    }
}

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

protected void bindCollectionWithJoinTable(GrailsDomainClassProperty property, Mappings mappings,
        Collection collection, PropertyConfig config, String sessionFactoryBeanName) {

    NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);

    SimpleValue element;/*from  w w  w  .  ja va  2  s  .co m*/
    if (property.isBasicCollectionType()) {
        element = new SimpleValue(mappings, collection.getCollectionTable());
    } else {
        // for a normal unidirectional one-to-many we use a join column
        element = new ManyToOne(mappings, collection.getCollectionTable());
        bindUnidirectionalOneToManyInverseValues(property, (ManyToOne) element);
    }
    collection.setInverse(false);

    String columnName;

    final boolean hasJoinColumnMapping = hasJoinColumnMapping(config);
    if (property.isBasicCollectionType()) {
        final Class<?> referencedType = property.getReferencedPropertyType();
        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.getDomainClass()));
            if (typeName == null) {
                Type type = mappings.getTypeResolver().basic(className);
                if (type != null) {
                    typeName = type.getName();
                }
            }
            if (typeName == null) {
                String domainName = property.getDomainClass().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(getColumnForSimpleValue(element), config.getJoinTable().getColumn());
            }
        }
    } else {
        final GrailsDomainClass domainClass = property.getReferencedDomainClass();

        Mapping m = getMapping(domainClass.getClazz());
        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(domainClass.getPropertyName())
                        + FOREIGN_KEY_SUFFIX;
            }

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

    collection.setElement(element);

    bindCollectionForPropertyConfig(collection, config);
}

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

/**
 * First pass to bind collection to Hibernate metamodel, sets up second pass
 *
 * @param property   The GrailsDomainClassProperty instance
 * @param collection The collection/* www .  ja  va2s  .c o  m*/
 * @param owner      The owning persistent class
 * @param mappings   The Hibernate mappings instance
 * @param path
 */
protected void bindCollection(GrailsDomainClassProperty property, Collection collection, PersistentClass owner,
        Mappings mappings, String path, String sessionFactoryBeanName) {

    // set role
    String propertyName = getNameForPropertyAndPath(property, path);
    collection.setRole(qualify(property.getDomainClass().getFullName(), propertyName));

    PropertyConfig pc = getPropertyConfig(property);
    // configure eager fetching
    if (property.getFetchMode() == GrailsDomainClassProperty.FETCH_EAGER) {
        collection.setFetchMode(FetchMode.JOIN);
    } else if (pc != null && pc.getFetch() != null) {
        collection.setFetchMode(pc.getFetch());
    } else {
        collection.setFetchMode(FetchMode.DEFAULT);
    }

    if (pc != null && pc.getCascade() != null) {
        collection.setOrphanDelete(pc.getCascade().equals(CASCADE_ALL_DELETE_ORPHAN));
    }
    // if it's a one-to-many mapping
    if (shouldBindCollectionWithForeignKey(property)) {
        OneToMany oneToMany = new OneToMany(mappings, collection.getOwner());
        collection.setElement(oneToMany);
        bindOneToMany(property, oneToMany, mappings);
    } else {
        bindCollectionTable(property, mappings, collection, owner.getTable(), sessionFactoryBeanName);

        if (!property.isOwningSide()) {
            collection.setInverse(true);
        }
    }

    if (pc != null && pc.getBatchSize() != null) {
        collection.setBatchSize(pc.getBatchSize().intValue());
    }

    // set up second pass
    if (collection instanceof org.hibernate.mapping.Set) {
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.List) {
        mappings.addSecondPass(new ListSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.Map) {
        mappings.addSecondPass(new MapSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else { // Collection -> Bag
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    }
}

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.java

License:Apache License

private static void bindCollectionSecondPass(GrailsDomainClassProperty property, Mappings mappings,
        Map<?, ?> persistentClasses, Collection collection, String sessionFactoryBeanName) {

    PersistentClass associatedClass = null;

    if (LOG.isDebugEnabled())
        LOG.debug("Mapping collection: " + collection.getRole() + " -> "
                + collection.getCollectionTable().getName());

    PropertyConfig propConfig = getPropertyConfig(property);

    if (propConfig != null && !StringUtils.isBlank(propConfig.getSort())) {
        if (!property.isBidirectional() && property.isOneToMany()) {
            throw new GrailsDomainException("Default sort for associations ["
                    + property.getDomainClass().getName() + "->" + property.getName()
                    + "] are not supported with unidirectional one to many relationships.");
        }/* ww  w .j a va  2s  . c o m*/
        GrailsDomainClass referenced = property.getReferencedDomainClass();
        if (referenced != null) {
            GrailsDomainClassProperty propertyToSortBy = referenced.getPropertyByName(propConfig.getSort());

            String associatedClassName = property.getReferencedDomainClass().getFullName();

            associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
            if (associatedClass != null) {
                collection.setOrderBy(buildOrderByClause(propertyToSortBy.getName(), associatedClass,
                        collection.getRole(), propConfig.getOrder() != null ? propConfig.getOrder() : "asc"));
            }
        }
    }

    // Configure one-to-many
    if (collection.isOneToMany()) {

        GrailsDomainClass referenced = property.getReferencedDomainClass();
        Mapping m = getRootMapping(referenced);
        boolean tablePerSubclass = m != null && !m.getTablePerHierarchy();

        if (referenced != null && !referenced.isRoot() && !tablePerSubclass) {
            Mapping rootMapping = getRootMapping(referenced);
            String discriminatorColumnName = RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME;

            if (rootMapping != null) {
                final ColumnConfig discriminatorColumn = rootMapping.getDiscriminatorColumn();
                if (discriminatorColumn != null) {
                    discriminatorColumnName = discriminatorColumn.getName();
                }
                if (rootMapping.getDiscriminatorMap().get("formula") != null) {
                    discriminatorColumnName = (String) m.getDiscriminatorMap().get("formula");
                }
            }
            //NOTE: this will build the set for the in clause if it has sublcasses
            Set<String> discSet = buildDiscriminatorSet(referenced);
            String inclause = StringUtils.join(discSet, ',');

            collection.setWhere(discriminatorColumnName + " in (" + inclause + ")");
        }

        OneToMany oneToMany = (OneToMany) collection.getElement();
        String associatedClassName = oneToMany.getReferencedEntityName();

        associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
        // if there is no persistent class for the association throw exception
        if (associatedClass == null) {
            throw new MappingException(
                    "Association references unmapped class: " + oneToMany.getReferencedEntityName());
        }

        oneToMany.setAssociatedClass(associatedClass);
        if (shouldBindCollectionWithForeignKey(property)) {
            collection.setCollectionTable(associatedClass.getTable());
        }

        bindCollectionForPropertyConfig(collection, propConfig);
    }

    if (isSorted(property)) {
        collection.setSorted(true);
    }

    // setup the primary key references
    DependantValue key = createPrimaryKeyValue(mappings, property, collection, persistentClasses);

    // link a bidirectional relationship
    if (property.isBidirectional()) {
        GrailsDomainClassProperty otherSide = property.getOtherSide();
        if (otherSide.isManyToOne() && shouldBindCollectionWithForeignKey(property)) {
            linkBidirectionalOneToMany(collection, associatedClass, key, otherSide);
        } else if (property.isManyToMany() || Map.class.isAssignableFrom(property.getType())) {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    } else {
        if (hasJoinKeyMapping(propConfig)) {
            bindSimpleValue("long", key, false, propConfig.getJoinTable().getKey().getName(), mappings);
        } else {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    }
    collection.setKey(key);

    // get cache config
    if (propConfig != null) {
        CacheConfig cacheConfig = propConfig.getCache();
        if (cacheConfig != null) {
            collection.setCacheConcurrencyStrategy(cacheConfig.getUsage());
        }
    }

    // if we have a many-to-many
    if (property.isManyToMany() || isBidirectionalOneToManyMap(property)) {
        GrailsDomainClassProperty otherSide = property.getOtherSide();

        if (property.isBidirectional()) {
            if (LOG.isDebugEnabled())
                LOG.debug("[GrailsDomainBinder] Mapping other side " + otherSide.getDomainClass().getName()
                        + "." + otherSide.getName() + " -> " + collection.getCollectionTable().getName()
                        + " as ManyToOne");
            ManyToOne element = new ManyToOne(mappings, collection.getCollectionTable());
            bindManyToMany(otherSide, element, mappings, sessionFactoryBeanName);
            collection.setElement(element);
            bindCollectionForPropertyConfig(collection, propConfig);
            if (property.isCircular()) {
                collection.setInverse(false);
            }
        } else {
            // TODO support unidirectional many-to-many
        }
    } else if (shouldCollectionBindWithJoinColumn(property)) {
        bindCollectionWithJoinTable(property, mappings, collection, propConfig, sessionFactoryBeanName);

    } else if (isUnidirectionalOneToMany(property)) {
        // for non-inverse one-to-many, with a not-null fk, add a backref!
        // there are problems with list and map mappings and join columns relating to duplicate key constraints
        // TODO change this when HHH-1268 is resolved
        bindUnidirectionalOneToMany(property, mappings, collection);
    }
}

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.java

License:Apache License

private static void bindCollectionWithJoinTable(GrailsDomainClassProperty property, Mappings mappings,
        Collection collection, PropertyConfig config, String sessionFactoryBeanName) {

    NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);

    SimpleValue element;/*from ww w. j  av a  2  s.  co m*/
    if (property.isBasicCollectionType()) {
        element = new SimpleValue(mappings, collection.getCollectionTable());
    } else {
        // for a normal unidirectional one-to-many we use a join column
        element = new ManyToOne(mappings, collection.getCollectionTable());
        bindUnidirectionalOneToManyInverseValues(property, (ManyToOne) element);
    }
    collection.setInverse(false);

    String columnName;

    final boolean hasJoinColumnMapping = hasJoinColumnMapping(config);
    if (property.isBasicCollectionType()) {
        final Class<?> referencedType = property.getReferencedPropertyType();
        String className = referencedType.getName();
        final boolean isEnum = GrailsClassUtils.isJdk5Enum(referencedType);
        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.getDomainClass()));
            if (typeName == null) {
                Type type = mappings.getTypeResolver().basic(className);
                if (type != null) {
                    typeName = type.getName();
                }
            }
            if (typeName == null) {
                String domainName = property.getDomainClass().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(getColumnForSimpleValue(element), config.getJoinTable().getColumn());
            }
        }
    } else {
        final GrailsDomainClass domainClass = property.getReferencedDomainClass();

        Mapping m = getMapping(domainClass.getClazz());
        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(domainClass.getPropertyName())
                        + FOREIGN_KEY_SUFFIX;
            }

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

    collection.setElement(element);

    bindCollectionForPropertyConfig(collection, config);
}

From source file:org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.java

License:Apache License

/**
 * First pass to bind collection to Hibernate metamodel, sets up second pass
 *
 * @param property   The GrailsDomainClassProperty instance
 * @param collection The collection//from www . ja  va 2  s.  c  o m
 * @param owner      The owning persistent class
 * @param mappings   The Hibernate mappings instance
 * @param path
 */
private static void bindCollection(GrailsDomainClassProperty property, Collection collection,
        PersistentClass owner, Mappings mappings, String path, String sessionFactoryBeanName) {

    // set role
    String propertyName = getNameForPropertyAndPath(property, path);
    collection.setRole(StringHelper.qualify(property.getDomainClass().getFullName(), propertyName));

    PropertyConfig pc = getPropertyConfig(property);
    // configure eager fetching
    if (property.getFetchMode() == GrailsDomainClassProperty.FETCH_EAGER) {
        collection.setFetchMode(FetchMode.JOIN);
    } else if (pc != null && pc.getFetch() != null) {
        collection.setFetchMode(pc.getFetch());
    } else {
        collection.setFetchMode(FetchMode.DEFAULT);
    }

    if (pc != null && pc.getCascade() != null) {
        collection.setOrphanDelete(pc.getCascade().equals(CASCADE_ALL_DELETE_ORPHAN));
    }
    // if it's a one-to-many mapping
    if (shouldBindCollectionWithForeignKey(property)) {
        OneToMany oneToMany = new OneToMany(mappings, collection.getOwner());
        collection.setElement(oneToMany);
        bindOneToMany(property, oneToMany, mappings);
    } else {
        bindCollectionTable(property, mappings, collection, owner.getTable(), sessionFactoryBeanName);

        if (!property.isOwningSide()) {
            collection.setInverse(true);
        }
    }

    if (pc != null && pc.getBatchSize() != null) {
        collection.setBatchSize(pc.getBatchSize().intValue());
    }

    // set up second pass
    if (collection instanceof org.hibernate.mapping.Set) {
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.List) {
        mappings.addSecondPass(new ListSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.Map) {
        mappings.addSecondPass(new MapSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else { // Collection -> Bag
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    }
}

From source file:org.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

protected void bindCollectionSecondPass(ToMany property, Mappings mappings, Map<?, ?> persistentClasses,
        Collection collection, String sessionFactoryBeanName) {

    PersistentClass associatedClass = null;

    if (LOG.isDebugEnabled())
        LOG.debug("Mapping collection: " + collection.getRole() + " -> "
                + collection.getCollectionTable().getName());

    PropertyConfig propConfig = getPropertyConfig(property);

    if (propConfig != null && StringUtils.hasText(propConfig.getSort())) {
        if (!property.isBidirectional()
                && (property instanceof org.grails.datastore.mapping.model.types.OneToMany)) {
            throw new DatastoreConfigurationException("Default sort for associations ["
                    + property.getOwner().getName() + "->" + property.getName()
                    + "] are not supported with unidirectional one to many relationships.");
        }//from   www  . j  a  v  a2 s.  c o m
        PersistentEntity referenced = property.getAssociatedEntity();
        if (referenced != null) {
            PersistentProperty propertyToSortBy = referenced.getPropertyByName(propConfig.getSort());

            String associatedClassName = property.getAssociatedEntity().getName();

            associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
            if (associatedClass != null) {
                collection.setOrderBy(buildOrderByClause(propertyToSortBy.getName(), associatedClass,
                        collection.getRole(), propConfig.getOrder() != null ? propConfig.getOrder() : "asc"));
            }
        }
    }

    // Configure one-to-many
    if (collection.isOneToMany()) {

        PersistentEntity referenced = property.getAssociatedEntity();
        Mapping m = getRootMapping(referenced);
        boolean tablePerSubclass = m != null && !m.getTablePerHierarchy();

        if (referenced != null && !referenced.isRoot() && !tablePerSubclass) {
            Mapping rootMapping = getRootMapping(referenced);
            String discriminatorColumnName = RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME;

            if (rootMapping != null) {
                final ColumnConfig discriminatorColumn = rootMapping.getDiscriminatorColumn();
                if (discriminatorColumn != null) {
                    discriminatorColumnName = discriminatorColumn.getName();
                }
                if (rootMapping.getDiscriminatorMap().get("formula") != null) {
                    discriminatorColumnName = (String) m.getDiscriminatorMap().get("formula");
                }
            }
            //NOTE: this will build the set for the in clause if it has sublcasses
            Set<String> discSet = buildDiscriminatorSet((HibernatePersistentEntity) referenced);
            String inclause = DefaultGroovyMethods.join(discSet, ",");

            collection.setWhere(discriminatorColumnName + " in (" + inclause + ")");
        }

        OneToMany oneToMany = (OneToMany) collection.getElement();
        String associatedClassName = oneToMany.getReferencedEntityName();

        associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
        // if there is no persistent class for the association throw exception
        if (associatedClass == null) {
            throw new MappingException(
                    "Association references unmapped class: " + oneToMany.getReferencedEntityName());
        }

        oneToMany.setAssociatedClass(associatedClass);
        if (shouldBindCollectionWithForeignKey(property)) {
            collection.setCollectionTable(associatedClass.getTable());
        }

        bindCollectionForPropertyConfig(collection, propConfig);
    }

    if (isSorted(property)) {
        collection.setSorted(true);
    }

    // setup the primary key references
    DependantValue key = createPrimaryKeyValue(mappings, property, collection, persistentClasses);

    // link a bidirectional relationship
    if (property.isBidirectional()) {
        Association otherSide = property.getInverseSide();
        if ((otherSide instanceof org.grails.datastore.mapping.model.types.ToOne)
                && shouldBindCollectionWithForeignKey(property)) {
            linkBidirectionalOneToMany(collection, associatedClass, key, otherSide);
        } else if ((otherSide instanceof ManyToMany) || Map.class.isAssignableFrom(property.getType())) {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    } else {
        if (hasJoinKeyMapping(propConfig)) {
            bindSimpleValue("long", key, false, propConfig.getJoinTable().getKey().getName(), mappings);
        } else {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    }
    collection.setKey(key);

    // get cache config
    if (propConfig != null) {
        CacheConfig cacheConfig = propConfig.getCache();
        if (cacheConfig != null) {
            collection.setCacheConcurrencyStrategy(cacheConfig.getUsage());
        }
    }

    // if we have a many-to-many
    final boolean isManyToMany = property instanceof ManyToMany;
    if (isManyToMany || isBidirectionalOneToManyMap(property)) {
        PersistentProperty otherSide = property.getInverseSide();

        if (property.isBidirectional()) {
            if (LOG.isDebugEnabled())
                LOG.debug("[GrailsDomainBinder] Mapping other side " + otherSide.getOwner().getName() + "."
                        + otherSide.getName() + " -> " + collection.getCollectionTable().getName()
                        + " as ManyToOne");
            ManyToOne element = new ManyToOne(mappings, collection.getCollectionTable());
            bindManyToMany((Association) otherSide, element, mappings, sessionFactoryBeanName);
            collection.setElement(element);
            bindCollectionForPropertyConfig(collection, propConfig);
            if (property.isCircular()) {
                collection.setInverse(false);
            }
        } else {
            // TODO support unidirectional many-to-many
        }
    } else if (shouldCollectionBindWithJoinColumn(property)) {
        bindCollectionWithJoinTable(property, mappings, collection, propConfig, sessionFactoryBeanName);

    } else if (isUnidirectionalOneToMany(property)) {
        // for non-inverse one-to-many, with a not-null fk, add a backref!
        // there are problems with list and map mappings and join columns relating to duplicate key constraints
        // TODO change this when HHH-1268 is resolved
        bindUnidirectionalOneToMany((org.grails.datastore.mapping.model.types.OneToMany) property, mappings,
                collection);
    }
}

From source file:org.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

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

    NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName);

    SimpleValue element;//from  w  ww .  ja v  a 2 s.c om
    final boolean isBasicCollectionType = property instanceof Basic;
    if (isBasicCollectionType) {
        element = new SimpleValue(mappings, collection.getCollectionTable());
    } else {
        // for a normal unidirectional one-to-many we use a join column
        element = new ManyToOne(mappings, 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.getTypeResolver().basic(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);
}

From source file:org.grails.orm.hibernate.cfg.AbstractGrailsDomainBinder.java

License:Apache License

/**
 * First pass to bind collection to Hibernate metamodel, sets up second pass
 *
 * @param property   The GrailsDomainClassProperty instance
 * @param collection The collection/*from   w ww .j a v a 2 s.  co  m*/
 * @param owner      The owning persistent class
 * @param mappings   The Hibernate mappings instance
 * @param path
 */
protected void bindCollection(ToMany property, Collection collection, PersistentClass owner, Mappings mappings,
        String path, String sessionFactoryBeanName) {

    // set role
    String propertyName = getNameForPropertyAndPath(property, path);
    collection.setRole(qualify(property.getOwner().getName(), propertyName));

    PropertyConfig pc = getPropertyConfig(property);
    // configure eager fetching
    final FetchMode fetchMode = pc.getFetchMode();
    if (fetchMode == FetchMode.JOIN) {
        collection.setFetchMode(FetchMode.JOIN);
    } else if (pc.getFetchMode() != null) {
        collection.setFetchMode(pc.getFetchMode());
    } else {
        collection.setFetchMode(FetchMode.DEFAULT);
    }

    if (pc.getCascade() != null) {
        collection.setOrphanDelete(pc.getCascade().equals(CASCADE_ALL_DELETE_ORPHAN));
    }
    // if it's a one-to-many mapping
    if (shouldBindCollectionWithForeignKey(property)) {
        OneToMany oneToMany = new OneToMany(mappings, collection.getOwner());
        collection.setElement(oneToMany);
        bindOneToMany((org.grails.datastore.mapping.model.types.OneToMany) property, oneToMany, mappings);
    } else {
        bindCollectionTable(property, mappings, collection, owner.getTable(), sessionFactoryBeanName);

        if (!property.isOwningSide()) {
            collection.setInverse(true);
        }
    }

    if (pc.getBatchSize() != null) {
        collection.setBatchSize(pc.getBatchSize());
    }

    // set up second pass
    if (collection instanceof org.hibernate.mapping.Set) {
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.List) {
        mappings.addSecondPass(new ListSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else if (collection instanceof org.hibernate.mapping.Map) {
        mappings.addSecondPass(new MapSecondPass(property, mappings, collection, sessionFactoryBeanName));
    } else { // Collection -> Bag
        mappings.addSecondPass(
                new GrailsCollectionSecondPass(property, mappings, collection, sessionFactoryBeanName));
    }
}

From source file:org.grails.orm.hibernate.cfg.GrailsDomainBinder.java

License:Apache License

protected void bindCollectionSecondPass(ToMany property, InFlightMetadataCollector mappings,
        Map<?, ?> persistentClasses, Collection collection, String sessionFactoryBeanName) {

    PersistentClass associatedClass = null;

    if (LOG.isDebugEnabled())
        LOG.debug("Mapping collection: " + collection.getRole() + " -> "
                + collection.getCollectionTable().getName());

    PropertyConfig propConfig = getPropertyConfig(property);

    PersistentEntity referenced = property.getAssociatedEntity();
    if (propConfig != null && StringUtils.hasText(propConfig.getSort())) {
        if (!property.isBidirectional()
                && (property instanceof org.grails.datastore.mapping.model.types.OneToMany)) {
            throw new DatastoreConfigurationException("Default sort for associations ["
                    + property.getOwner().getName() + "->" + property.getName()
                    + "] are not supported with unidirectional one to many relationships.");
        }//from   w  ww  .j a  va  2s .  co  m
        if (referenced != null) {
            PersistentProperty propertyToSortBy = referenced.getPropertyByName(propConfig.getSort());

            String associatedClassName = property.getAssociatedEntity().getName();

            associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
            if (associatedClass != null) {
                collection.setOrderBy(buildOrderByClause(propertyToSortBy.getName(), associatedClass,
                        collection.getRole(), propConfig.getOrder() != null ? propConfig.getOrder() : "asc"));
            }
        }
    }

    // Configure one-to-many
    if (collection.isOneToMany()) {

        Mapping m = getRootMapping(referenced);
        boolean tablePerSubclass = m != null && !m.getTablePerHierarchy();

        if (referenced != null && !referenced.isRoot() && !tablePerSubclass) {
            Mapping rootMapping = getRootMapping(referenced);
            String discriminatorColumnName = RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME;

            if (rootMapping != null) {
                DiscriminatorConfig discriminatorConfig = rootMapping.getDiscriminator();
                if (discriminatorConfig != null) {
                    final ColumnConfig discriminatorColumn = discriminatorConfig.getColumn();
                    if (discriminatorColumn != null) {
                        discriminatorColumnName = discriminatorColumn.getName();
                    }
                    if (discriminatorConfig.getFormula() != null) {
                        discriminatorColumnName = discriminatorConfig.getFormula();
                    }
                }
            }
            //NOTE: this will build the set for the in clause if it has sublcasses
            Set<String> discSet = buildDiscriminatorSet((HibernatePersistentEntity) referenced);
            String inclause = DefaultGroovyMethods.join(discSet, ",");

            collection.setWhere(discriminatorColumnName + " in (" + inclause + ")");
        }

        OneToMany oneToMany = (OneToMany) collection.getElement();
        String associatedClassName = oneToMany.getReferencedEntityName();

        associatedClass = (PersistentClass) persistentClasses.get(associatedClassName);
        // if there is no persistent class for the association throw exception
        if (associatedClass == null) {
            throw new MappingException(
                    "Association references unmapped class: " + oneToMany.getReferencedEntityName());
        }

        oneToMany.setAssociatedClass(associatedClass);
        if (shouldBindCollectionWithForeignKey(property)) {
            collection.setCollectionTable(associatedClass.getTable());
        }

        bindCollectionForPropertyConfig(collection, propConfig);
    }

    if (referenced != null && referenced.isMultiTenant()) {
        String filterCondition = getMultiTenantFilterCondition(sessionFactoryBeanName, referenced);
        if (filterCondition != null) {
            collection.addFilter(GormProperties.TENANT_IDENTITY, filterCondition, true,
                    Collections.<String, String>emptyMap(), Collections.<String, String>emptyMap());
        }
    }

    if (isSorted(property)) {
        collection.setSorted(true);
    }

    // setup the primary key references
    DependantValue key = createPrimaryKeyValue(mappings, property, collection, persistentClasses);

    // link a bidirectional relationship
    if (property.isBidirectional()) {
        Association otherSide = property.getInverseSide();
        if ((otherSide instanceof org.grails.datastore.mapping.model.types.ToOne)
                && shouldBindCollectionWithForeignKey(property)) {
            linkBidirectionalOneToMany(collection, associatedClass, key, otherSide);
        } else if ((otherSide instanceof ManyToMany) || Map.class.isAssignableFrom(property.getType())) {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    } else {
        if (hasJoinKeyMapping(propConfig)) {
            bindSimpleValue("long", key, false, propConfig.getJoinTable().getKey().getName(), mappings);
        } else {
            bindDependentKeyValue(property, key, mappings, sessionFactoryBeanName);
        }
    }
    collection.setKey(key);

    // get cache config
    if (propConfig != null) {
        CacheConfig cacheConfig = propConfig.getCache();
        if (cacheConfig != null) {
            collection.setCacheConcurrencyStrategy(cacheConfig.getUsage());
        }
    }

    // if we have a many-to-many
    final boolean isManyToMany = property instanceof ManyToMany;
    if (isManyToMany || isBidirectionalOneToManyMap(property)) {
        PersistentProperty otherSide = property.getInverseSide();

        if (property.isBidirectional()) {
            if (LOG.isDebugEnabled())
                LOG.debug("[GrailsDomainBinder] Mapping other side " + otherSide.getOwner().getName() + "."
                        + otherSide.getName() + " -> " + collection.getCollectionTable().getName()
                        + " as ManyToOne");
            ManyToOne element = new ManyToOne(mappings, collection.getCollectionTable());
            bindManyToMany((Association) otherSide, element, mappings, sessionFactoryBeanName);
            collection.setElement(element);
            bindCollectionForPropertyConfig(collection, propConfig);
            if (property.isCircular()) {
                collection.setInverse(false);
            }
        } else {
            // TODO support unidirectional many-to-many
        }
    } else if (shouldCollectionBindWithJoinColumn(property)) {
        bindCollectionWithJoinTable(property, mappings, collection, propConfig, sessionFactoryBeanName);

    } else if (isUnidirectionalOneToMany(property)) {
        // for non-inverse one-to-many, with a not-null fk, add a backref!
        // there are problems with list and map mappings and join columns relating to duplicate key constraints
        // TODO change this when HHH-1268 is resolved
        bindUnidirectionalOneToMany((org.grails.datastore.mapping.model.types.OneToMany) property, mappings,
                collection);
    }
}