public static void bindOneToMany(Element node, OneToMany oneToMany, Mappings mappings) throws MappingException { oneToMany.setReferencedEntityName( getEntityName( node, mappings ) ); String embed = node.attributeValue( "embed-xml" ); // sometimes embed is set to the default value when not specified in the mapping, // so can't seem to determine if an attribute was explicitly set; // log a warning if embed has a value different from the default. if ( !StringHelper.isEmpty( embed ) && !"true".equals( embed ) ) { LOG.embedXmlAttributesNoLongerSupported(); } oneToMany.setEmbedded( embed == null || "true".equals( embed ) ); String notFound = node.attributeValue( "not-found" ); oneToMany.setIgnoreNotFound( "ignore".equals( notFound ) ); }
public void doSecondPass(java.util.Map persistentClasses) throws MappingException { final boolean debugEnabled = LOG.isDebugEnabled(); if ( debugEnabled ) { LOG.debugf( "Second pass for collection: %s", collection.getRole() ); } secondPass( persistentClasses, localInheritedMetas ); // using local since the inheritedMetas at this point is not the correct map since it is always the empty map collection.createAllKeys(); if ( debugEnabled ) { String msg = "Mapped collection key: " + columns( collection.getKey() ); if ( collection.isIndexed() ) msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() ); if ( collection.isOneToMany() ) { msg += ", one-to-many: " + ( (OneToMany) collection.getElement() ).getReferencedEntityName(); } else { msg += ", element: " + columns( collection.getElement() ); } LOG.debug( msg ); } }
/** * Binds a unidirectional one-to-many creating a psuedo back reference property in the process. * * @param property * @param mappings * @param collection */ protected void bindUnidirectionalOneToMany(org.grails.datastore.mapping.model.types.OneToMany property, InFlightMetadataCollector mappings, Collection collection) { Value v = collection.getElement(); v.createForeignKey(); String entityName; if (v instanceof ManyToOne) { ManyToOne manyToOne = (ManyToOne) v; entityName = manyToOne.getReferencedEntityName(); } else { entityName = ((OneToMany) v).getReferencedEntityName(); } collection.setInverse(false); PersistentClass referenced = mappings.getEntityBinding(entityName); Backref prop = new Backref(); PersistentEntity owner = property.getOwner(); prop.setEntityName(owner.getName()); prop.setName(UNDERSCORE + addUnderscore(owner.getJavaClass().getSimpleName(), property.getName()) + "Backref"); prop.setUpdateable(false); prop.setInsertable(true); prop.setCollectionRole(collection.getRole()); prop.setValue(collection.getKey()); prop.setOptional(true); referenced.addProperty(prop); }
protected void createCollectionKeys() { collection.createAllKeys(); if (LOG.isDebugEnabled()) { String msg = "Mapped collection key: " + columns(collection.getKey()); if (collection.isIndexed()) msg += ", index: " + columns(((IndexedCollection) collection).getIndex()); if (collection.isOneToMany()) { msg += ", one-to-many: " + ((OneToMany) collection.getElement()).getReferencedEntityName(); } else { msg += ", element: " + columns(collection.getElement()); } LOG.debug(msg); } }
public void doSecondPass(java.util.Map persistentClasses) throws MappingException { if ( log.isDebugEnabled() ) log.debug( "Second pass for collection: " + collection.getRole() ); secondPass( persistentClasses, localInheritedMetas ); // using local since the inheritedMetas at this point is not the correct map since it is always the empty map collection.createAllKeys(); if ( log.isDebugEnabled() ) { String msg = "Mapped collection key: " + columns( collection.getKey() ); if ( collection.isIndexed() ) msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() ); if ( collection.isOneToMany() ) { msg += ", one-to-many: " + ( (OneToMany) collection.getElement() ).getReferencedEntityName(); } else { msg += ", element: " + columns( collection.getElement() ); } log.debug( msg ); } }
public void testProperCallbacks() { ValueVisitor vv = new ValueVisitorValidator(); new Any(new Table()).accept(vv); new Array(new RootClass()).accept(vv); new Bag(new RootClass()).accept(vv); new Component(new RootClass()).accept(vv); new DependantValue(null,null).accept(vv); new IdentifierBag(null).accept(vv); new List(null).accept(vv); new ManyToOne(null).accept(vv); new Map(null).accept(vv); new OneToMany(null).accept(vv); new OneToOne(null, new RootClass() ).accept(vv); new PrimitiveArray(null).accept(vv); new Set(null).accept(vv); new SimpleValue().accept(vv); }
/** * Called for Lists, arrays, primitive arrays */ public static void bindListSecondPass(Element node, List list, java.util.Map classes, Mappings mappings, java.util.Map inheritedMetas) throws MappingException { bindCollectionSecondPass( node, list, classes, mappings, inheritedMetas ); Element subnode = node.element( "list-index" ); if ( subnode == null ) subnode = node.element( "index" ); SimpleValue iv = new SimpleValue( mappings, list.getCollectionTable() ); bindSimpleValue( subnode, iv, list.isOneToMany(), IndexedCollection.DEFAULT_INDEX_COLUMN_NAME, mappings ); iv.setTypeName( "integer" ); list.setIndex( iv ); String baseIndex = subnode.attributeValue( "base" ); if ( baseIndex != null ) list.setBaseIndex( Integer.parseInt( baseIndex ) ); list.setIndexNodeName( subnode.attributeValue("node") ); if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) { String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName(); PersistentClass referenced = mappings.getClass( entityName ); IndexBackref ib = new IndexBackref(); ib.setName( '_' + list.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "IndexBackref" ); ib.setUpdateable( false ); ib.setSelectable( false ); ib.setCollectionRole( list.getRole() ); ib.setEntityName( list.getOwner().getEntityName() ); ib.setValue( list.getIndex() ); // ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next() // ).setNullable(false); referenced.addProperty( ib ); } }
private void bindIndex(final Mappings mappings) { if ( !indexColumn.isImplicit() ) { PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder( this.collection, StringHelper.qualify( this.collection.getRole(), "key" ), null, null, propertyHolder, mappings ); List list = (List) this.collection; if ( !list.isOneToMany() ) indexColumn.forceNotNull(); indexColumn.setPropertyHolder( valueHolder ); SimpleValueBinder value = new SimpleValueBinder(); value.setColumns( new Ejb3Column[] { indexColumn } ); value.setExplicitType( "integer" ); value.setMappings( mappings ); SimpleValue indexValue = value.make(); indexColumn.linkWithValue( indexValue ); list.setIndex( indexValue ); list.setBaseIndex( indexColumn.getBase() ); if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) { String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName(); PersistentClass referenced = mappings.getClass( entityName ); IndexBackref ib = new IndexBackref(); ib.setName( '_' + propertyName + "IndexBackref" ); ib.setUpdateable( false ); ib.setSelectable( false ); ib.setCollectionRole( list.getRole() ); ib.setEntityName( list.getOwner().getEntityName() ); ib.setValue( list.getIndex() ); referenced.addProperty( ib ); } } else { Collection coll = this.collection; throw new AnnotationException( "List/array has to be annotated with an @OrderColumn (or @IndexColumn): " + coll.getRole() ); } }
protected boolean shouldBindCollectionWithForeignKey(ToMany property) { return ((property instanceof org.grails.datastore.mapping.model.types.OneToMany) && property.isBidirectional() || !shouldCollectionBindWithJoinColumn(property)) && !Map.class.isAssignableFrom(property.getType()) && !(property instanceof ManyToMany) && !(property instanceof Basic); }
protected String getAssociationDescription(Association grailsProperty) { String assType = "unknown"; if (grailsProperty instanceof ManyToMany) { assType = "many-to-many"; } else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.OneToMany) { assType = "one-to-many"; } else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.OneToOne) { assType = "one-to-one"; } else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.ManyToOne) { assType = "many-to-one"; } else if (grailsProperty.isEmbedded()) { assType = "embedded"; } return assType; }
protected String getDefaultColumnName(PersistentProperty property, String sessionFactoryBeanName) { NamingStrategy namingStrategy = getNamingStrategy(sessionFactoryBeanName); String columnName = namingStrategy.propertyToColumnName(property.getName()); if (property instanceof Association) { Association association = (Association) property; boolean isBasic = property instanceof Basic; if(isBasic && ((PropertyConfig)property.getMapping().getMappedForm()).getType() != null ) { return columnName; } if (isBasic) { return getForeignKeyForPropertyDomainClass(property, sessionFactoryBeanName); } if (property instanceof ManyToMany) { return getForeignKeyForPropertyDomainClass(property, sessionFactoryBeanName); } if (!association.isBidirectional() && association instanceof org.grails.datastore.mapping.model.types.OneToMany) { String prefix = namingStrategy.classToTableName(property.getOwner().getName()); return addUnderscore(prefix, columnName) + FOREIGN_KEY_SUFFIX; } if (property.isInherited() && isBidirectionalManyToOne(property)) { return namingStrategy.propertyToColumnName(property.getOwner().getName()) + '_'+ columnName + FOREIGN_KEY_SUFFIX; } return columnName + FOREIGN_KEY_SUFFIX; } return columnName; }
/** * Called for Lists, arrays, primitive arrays */ public static void bindListSecondPass(Element node, List list, java.util.Map classes, Mappings mappings, java.util.Map inheritedMetas) throws MappingException { bindCollectionSecondPass( node, list, classes, mappings, inheritedMetas ); Element subnode = node.element( "list-index" ); if ( subnode == null ) subnode = node.element( "index" ); SimpleValue iv = new SimpleValue( list.getCollectionTable() ); bindSimpleValue( subnode, iv, list.isOneToMany(), IndexedCollection.DEFAULT_INDEX_COLUMN_NAME, mappings ); iv.setTypeName( "integer" ); list.setIndex( iv ); String baseIndex = subnode.attributeValue( "base" ); if ( baseIndex != null ) list.setBaseIndex( Integer.parseInt( baseIndex ) ); list.setIndexNodeName( subnode.attributeValue("node") ); if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) { String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName(); PersistentClass referenced = mappings.getClass( entityName ); IndexBackref ib = new IndexBackref(); ib.setName( '_' + node.attributeValue( "name" ) + "IndexBackref" ); ib.setUpdateable( false ); ib.setSelectable( false ); ib.setCollectionRole( list.getRole() ); ib.setEntityName( list.getOwner().getEntityName() ); ib.setValue( list.getIndex() ); // ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next() // ).setNullable(false); referenced.addProperty( ib ); } }
public String getEndName(String parentClassname, String childClassname) throws TypesInformationException { LOG.debug("Getting the association end name for " + parentClassname + " to " + childClassname); String identifier = getAssociationIdentifier(parentClassname, childClassname); String roleName = roleNames.get(identifier); if (roleName == null) { PersistentClass clazz = findPersistentClass(parentClassname); Iterator<?> propertyIter = clazz.getPropertyIterator(); while (propertyIter.hasNext()) { Property prop = (Property) propertyIter.next(); Value value = prop.getValue(); String referencedEntity = null; if (value instanceof Collection) { Value element = ((Collection) value).getElement(); if (element instanceof OneToMany) { referencedEntity = ((OneToMany) element).getReferencedEntityName(); } else if (element instanceof ToOne) { referencedEntity = ((ToOne) element).getReferencedEntityName(); } } else if (value instanceof ToOne) { referencedEntity = ((ToOne) value).getReferencedEntityName(); } if (childClassname.equals(referencedEntity)) { if (roleName != null) { // already found one association, so this is ambiguous throw new TypesInformationException("Association from " + parentClassname + " to " + childClassname + " is ambiguous. Please specify a valid role name"); } roleName = prop.getName(); } } } return roleName; }
protected void bindMapSecondPass(ToMany property, InFlightMetadataCollector mappings, Map<?, ?> persistentClasses, org.hibernate.mapping.Map map, String sessionFactoryBeanName) { bindCollectionSecondPass(property, mappings, persistentClasses, map, sessionFactoryBeanName); SimpleValue value = new SimpleValue(mappings, map.getCollectionTable()); bindSimpleValue(getIndexColumnType(property, STRING_TYPE), value, true, getIndexColumnName(property, sessionFactoryBeanName), mappings); PropertyConfig pc = getPropertyConfig(property); if (pc != null && pc.getIndexColumn() != null) { bindColumnConfigToColumn(property, getColumnForSimpleValue(value), getSingleColumnConfig(pc.getIndexColumn())); } if (!value.isTypeSpecified()) { throw new MappingException("map index element must specify a type: " + map.getRole()); } map.setIndex(value); if(!(property instanceof org.grails.datastore.mapping.model.types.OneToMany) && !(property instanceof ManyToMany)) { SimpleValue elt = new SimpleValue(mappings, map.getCollectionTable()); map.setElement(elt); String typeName = getTypeName(property,getPropertyConfig(property), getMapping(property.getOwner())); if (typeName == null ) { if(property instanceof Basic) { Basic basic = (Basic) property; typeName = basic.getComponentType().getName(); } } if(typeName == null || typeName.equals(Object.class.getName())) { typeName = StandardBasicTypes.STRING.getName(); } bindSimpleValue(typeName, elt, false, getMapElementName(property, sessionFactoryBeanName), mappings); elt.setTypeName(typeName); } map.setInverse(false); }
protected void bindListSecondPass(ToMany property, InFlightMetadataCollector mappings, Map<?, ?> persistentClasses, org.hibernate.mapping.List list, String sessionFactoryBeanName) { bindCollectionSecondPass(property, mappings, persistentClasses, list, sessionFactoryBeanName); String columnName = getIndexColumnName(property, sessionFactoryBeanName); final boolean isManyToMany = property instanceof ManyToMany; if (isManyToMany && !property.isOwningSide()) { throw new MappingException("Invalid association [" + property + "]. List collection types only supported on the owning side of a many-to-many relationship."); } Table collectionTable = list.getCollectionTable(); SimpleValue iv = new SimpleValue(mappings, collectionTable); bindSimpleValue("integer", iv, true, columnName, mappings); iv.setTypeName("integer"); list.setIndex(iv); list.setBaseIndex(0); list.setInverse(false); Value v = list.getElement(); v.createForeignKey(); if (property.isBidirectional()) { String entityName; Value element = list.getElement(); if (element instanceof ManyToOne) { ManyToOne manyToOne = (ManyToOne) element; entityName = manyToOne.getReferencedEntityName(); } else { entityName = ((OneToMany) element).getReferencedEntityName(); } PersistentClass referenced = mappings.getEntityBinding(entityName); Class<?> mappedClass = referenced.getMappedClass(); Mapping m = getMapping(mappedClass); boolean compositeIdProperty = isCompositeIdProperty(m, property.getInverseSide()); if (!compositeIdProperty) { Backref prop = new Backref(); final PersistentEntity owner = property.getOwner(); prop.setEntityName(owner.getName()); prop.setName(UNDERSCORE + addUnderscore(owner.getJavaClass().getSimpleName(), property.getName()) + "Backref"); prop.setSelectable(false); prop.setUpdateable(false); if (isManyToMany) { prop.setInsertable(false); } prop.setCollectionRole(list.getRole()); prop.setValue(list.getKey()); DependantValue value = (DependantValue) prop.getValue(); if (!property.isCircular()) { value.setNullable(false); } value.setUpdateable(true); prop.setOptional(false); referenced.addProperty(prop); } if ((!list.getKey().isNullable() && !list.isInverse()) || compositeIdProperty) { IndexBackref ib = new IndexBackref(); ib.setName(UNDERSCORE + property.getName() + "IndexBackref"); ib.setUpdateable(false); ib.setSelectable(false); if (isManyToMany) { ib.setInsertable(false); } ib.setCollectionRole(list.getRole()); ib.setEntityName(list.getOwner().getEntityName()); ib.setValue(list.getIndex()); referenced.addProperty(ib); } } }
/** * First pass to bind collection to Hibernate metamodel, sets up second pass * * @param property The GrailsDomainClassProperty instance * @param collection The collection * @param owner The owning persistent class * @param mappings The Hibernate mappings instance * @param path */ protected void bindCollection(ToMany property, Collection collection, PersistentClass owner, InFlightMetadataCollector 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)); } }
protected void bindOneToMany(org.grails.datastore.mapping.model.types.OneToMany currentGrailsProp, OneToMany one, InFlightMetadataCollector mappings) { one.setReferencedEntityName(currentGrailsProp.getAssociatedEntity().getName()); one.setIgnoreNotFound(true); }
protected void setCascadeBehaviour(PersistentProperty grailsProperty, Property prop) { String cascadeStrategy = "none"; // set to cascade all for the moment PersistentEntity domainClass = grailsProperty.getOwner(); PropertyConfig config = getPropertyConfig(grailsProperty); if (config != null && config.getCascade() != null) { cascadeStrategy = config.getCascade(); } else if (grailsProperty instanceof Association) { Association association = (Association) grailsProperty; PersistentEntity referenced = association.getAssociatedEntity(); if (isHasOne(association)) { cascadeStrategy = CASCADE_ALL; } else if (association instanceof org.grails.datastore.mapping.model.types.OneToOne) { if (referenced != null && association.isOwningSide()) { cascadeStrategy = CASCADE_ALL; } else { cascadeStrategy = CASCADE_SAVE_UPDATE; } } else if (association instanceof org.grails.datastore.mapping.model.types.OneToMany) { if (referenced != null && association.isOwningSide()) { cascadeStrategy = CASCADE_ALL; } else { cascadeStrategy = CASCADE_SAVE_UPDATE; } } else if (grailsProperty instanceof ManyToMany) { if ((referenced != null && referenced.isOwningEntity(domainClass)) || association.isCircular()) { cascadeStrategy = CASCADE_SAVE_UPDATE; } } else if (grailsProperty instanceof org.grails.datastore.mapping.model.types.ManyToOne) { if (referenced != null && referenced.isOwningEntity(domainClass) && !isCircularAssociation(grailsProperty)) { cascadeStrategy = CASCADE_ALL; } else if(isCompositeIdProperty((Mapping) domainClass.getMapping().getMappedForm(), grailsProperty)) { cascadeStrategy = CASCADE_ALL; } else { cascadeStrategy = CASCADE_NONE; } } else if (grailsProperty instanceof Basic) { cascadeStrategy = CASCADE_ALL; } else if (Map.class.isAssignableFrom(grailsProperty.getType())) { referenced = association.getAssociatedEntity(); if (referenced != null && referenced.isOwningEntity(domainClass)) { cascadeStrategy = CASCADE_ALL; } else { cascadeStrategy = CASCADE_SAVE_UPDATE; } } logCascadeMapping(association, cascadeStrategy, referenced); } prop.setCascade(cascadeStrategy); }
public Object accept(OneToMany many) { return validate(OneToMany.class, many); }
public String getRoleName(String parentClassname, String childClassname) throws TypesInformationException { String identifier = getAssociationIdentifier(parentClassname, childClassname); String roleName = roleNames.get(identifier); if (roleName == null) { PersistentClass clazz = configuration.getClassMapping(parentClassname); Iterator<?> propertyIter = clazz.getPropertyIterator(); while (propertyIter.hasNext()) { Property prop = (Property) propertyIter.next(); Value value = prop.getValue(); String referencedEntity = null; if (value instanceof Collection) { Value element = ((Collection) value).getElement(); if (element instanceof OneToMany) { referencedEntity = ((OneToMany) element).getReferencedEntityName(); } else if (element instanceof ToOne) { referencedEntity = ((ToOne) element).getReferencedEntityName(); } } else if (value instanceof ToOne) { referencedEntity = ((ToOne) value).getReferencedEntityName(); } if (childClassname.equals(referencedEntity)) { if (roleName != null) { // already found one association, so this is ambiguous throw new TypesInformationException("Association from " + parentClassname + " to " + childClassname + " is ambiguous. Please specify a valid role name"); } roleName = prop.getName(); } } if (roleName == null && reflectionFallback) { LOG.debug("No role name found for " + identifier + " using hibernate configuration, trying reflection"); Class<?> parentClass = null; try { parentClass = Class.forName(parentClassname); } catch (ClassNotFoundException ex) { LOG.error("Could not load parent class: " + ex.getMessage()); throw new TypesInformationException("Could not load parent class: " + ex.getMessage()); } Field[] fields = parentClass.getDeclaredFields(); for (Field f : fields) { // if collection, inspect the collection for type Class<?> fieldType = f.getType(); if (java.util.Collection.class.isAssignableFrom(fieldType)) { Type generic = f.getGenericType(); if (generic instanceof ParameterizedType) { Type contents = ((ParameterizedType) generic).getActualTypeArguments()[0]; if (contents instanceof Class && childClassname.equals(((Class<?>) contents).getName())) { roleName = f.getName(); } } } else if (fieldType.getName().equals(childClassname)) { if (roleName != null) { // already found one association, so this is ambiguous throw new TypesInformationException("Association from " + parentClassname + " to " + childClassname + " is ambiguous. Please specify a valid role name"); } roleName = f.getName(); } } } } return roleName; }
public String getRoleName(String parentClassname, String childClassname) throws TypesInformationException { String identifier = getAssociationIdentifier(parentClassname, childClassname); String roleName = roleNames.get(identifier); if (roleName == null) { PersistentClass clazz = configuration.getClassMapping(parentClassname); Iterator<?> propertyIter = clazz.getPropertyIterator(); while (propertyIter.hasNext()) { Property prop = (Property) propertyIter.next(); Value value = prop.getValue(); String referencedEntity = null; if (value instanceof Collection) { Value element = ((Collection) value).getElement(); if (element instanceof OneToMany) { referencedEntity = ((OneToMany) element).getReferencedEntityName(); } else if (element instanceof ToOne) { referencedEntity = ((ToOne) element).getReferencedEntityName(); } } else if (value instanceof ToOne) { referencedEntity = ((ToOne) value).getReferencedEntityName(); } if (childClassname.equals(referencedEntity)) { if (roleName != null) { // already found one association, so this is ambiguous throw new TypesInformationException("Association from " + parentClassname + " to " + childClassname + " is ambiguous. Please specify a valid role name"); } roleName = prop.getName(); } } if (roleName == null && reflectionFallback) { LOG.debug("No role name found for " + identifier + " using hibernate configuration, trying reflection"); Class<?> parentClass = null; try { parentClass = Class.forName(parentClassname); } catch (ClassNotFoundException ex) { LOG.error("Could not load parent class: " + ex.getMessage()); throw new TypesInformationException("Could not load parent class: " + ex.getMessage()); } Field[] fields = parentClass.getDeclaredFields(); for (Field f : fields) { // if collection, inspect the collection for type Class<?> fieldType = f.getType(); if (java.util.Collection.class.isAssignableFrom(fieldType)) { Type generic = f.getGenericType(); if (generic instanceof ParameterizedType) { Type contents = ((ParameterizedType) generic).getActualTypeArguments()[0]; if (contents instanceof Class && childClassname.equals(((Class) contents).getName())) { roleName = f.getName(); } } } else if (fieldType.getName().equals(childClassname)) { if (roleName != null) { // already found one association, so this is ambiguous throw new TypesInformationException("Association from " + parentClassname + " to " + childClassname + " is ambiguous. Please specify a valid role name"); } roleName = f.getName(); } } } } return roleName; }
public static void bindOneToMany(Element node, OneToMany oneToMany, Mappings mappings) throws MappingException { oneToMany.setReferencedEntityName( getEntityName( node, mappings ) ); String embed = node.attributeValue( "embed-xml" ); oneToMany.setEmbedded( embed == null || "true".equals( embed ) ); String notFound = node.attributeValue( "not-found" ); oneToMany.setIgnoreNotFound( "ignore".equals( notFound ) ); }
/** * Checks whether a property is a unidirectional non-circular one-to-many * * @param property The property to check * @return true if it is unidirectional and a one-to-many */ protected boolean isUnidirectionalOneToMany(PersistentProperty property) { return ((property instanceof org.grails.datastore.mapping.model.types.OneToMany) && !((Association)property).isBidirectional()); }