protected override JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory) { if (criteria.IsJoin(path)) { return(JoinType.InnerJoin); } else { FetchMode fm = criteria.GetFetchMode(path); //fm==null || - an Enum can't be null if (fm == FetchMode.Default) { return(base.GetJoinType(type, config, path, table, foreignKeyColumns, factory)); } else { return(fm == FetchMode.Eager ? JoinType.LeftOuterJoin : JoinType.None); } } }
protected virtual JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory ) { bool mappingDefault = IsJoinedFetchEnabledByDefault( config, type, factory ); return IsJoinedFetchEnabled( type, mappingDefault, path, table, foreignKeyColumns) ? JoinType.LeftOuterJoin : JoinType.None; }
protected virtual JoinType GetJoinType(IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory) { bool mappingDefault = IsJoinedFetchEnabledByDefault(config, type, factory); return(IsJoinedFetchEnabled(type, mappingDefault, path, table, foreignKeyColumns) ? JoinType.LeftOuterJoin : JoinType.None); }
public DynamicComponentType( string[ ] propertyNames, IType[ ] propertyTypes, OuterJoinFetchStrategy[ ] joinedFetch, Cascades.CascadeStyle[ ] cascade ) { this.propertyNames = propertyNames; this.propertyTypes = propertyTypes; this.joinedFetch = joinedFetch; this.cascade = cascade; propertySpan = propertyTypes.Length; }
/// <summary> /// /// </summary> /// <param name="componentClass"></param> /// <param name="propertyNames"></param> /// <param name="propertyGetters"></param> /// <param name="propertySetters"></param> /// <param name="foundCustomAcessor"></param> /// <param name="propertyTypes"></param> /// <param name="joinedFetch"></param> /// <param name="cascade"></param> /// <param name="parentProperty"></param> public ComponentType( System.Type componentClass, string[ ] propertyNames, IGetter[ ] propertyGetters, ISetter[ ] propertySetters, // currently not used, see the comment near the end of the method body bool foundCustomAcessor, IType[ ] propertyTypes, OuterJoinFetchStrategy[ ] joinedFetch, Cascades.CascadeStyle[ ] cascade, string parentProperty) { this.componentClass = componentClass; this.propertyTypes = propertyTypes; propertySpan = propertyNames.Length; getters = propertyGetters; setters = propertySetters; string[ ] getterNames = new string[propertySpan]; string[ ] setterNames = new string[propertySpan]; System.Type[ ] propTypes = new System.Type[propertySpan]; for( int i = 0; i < propertySpan; i++ ) { getterNames[ i ] = getters[ i ].PropertyName; setterNames[ i ] = setters[ i ].PropertyName; propTypes[ i ] = getters[ i ].ReturnType; } if( parentProperty == null ) { parentSetter = null; parentGetter = null; } else { IPropertyAccessor pa = PropertyAccessorFactory.GetPropertyAccessor( null ); parentSetter = pa.GetSetter( componentClass, parentProperty ); parentGetter = pa.GetGetter( componentClass, parentProperty ); } this.propertyNames = propertyNames; this.cascade = cascade; this.joinedFetch = joinedFetch; // NH: reflection optimizer works with custom accessors if( /*!foundCustomAcessor &&*/ Cfg.Environment.UseReflectionOptimizer ) { this.getset = GetSetHelperFactory.Create(componentClass, setters, getters); } }
protected override JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory ) { JoinType joinType = base.GetJoinType(type, config, path, table, foreignKeyColumns, factory); // We can use an inner-join for the many-to-many if (joinType == JoinType.LeftOuterJoin && string.Empty.Equals(path)) { joinType = JoinType.InnerJoin; } return(joinType); }
/// <summary> /// Does the mapping, and Hibernate default semantics, specify that /// this association should be fetched by outer joining /// </summary> /// <param name="config"></param> /// <param name="type"></param> /// <param name="factory"></param> /// <returns></returns> protected bool IsJoinedFetchEnabledByDefault(OuterJoinFetchStrategy config, IAssociationType type, ISessionFactoryImplementor factory) { if (!type.IsEntityType && !type.IsPersistentCollectionType) { return(false); } else { switch (config) { case OuterJoinFetchStrategy.Eager: return(true); case OuterJoinFetchStrategy.Lazy: return(false); case OuterJoinFetchStrategy.Auto: if (!factory.IsOuterJoinedFetchEnabled) { return(false); } if (type.IsEntityType) { EntityType entityType = type as EntityType; IClassPersister persister = factory.GetPersister(entityType.AssociatedClass); return(!persister.HasProxy || ( entityType.IsOneToOne && ((OneToOneType)entityType).IsNullable )); } else { return(false); } default: throw new ArgumentOutOfRangeException("config", config, "Unknown OJ strategy " + config.ToString()); } } }
public static void BindComponent( XmlNode node, Component model, System.Type reflectedClass, string className, string path, bool isNullable, Mappings mappings ) { XmlAttribute classNode = node.Attributes[ "class" ]; if( "dynamic-component".Equals( node.Name ) ) { model.IsEmbedded = false; model.IsDynamic = true; } else if( classNode != null ) { model.ComponentClass = ClassForNameChecked( classNode.Value, mappings, "component class not found: {0}" ); model.IsEmbedded = false; } else if( reflectedClass != null ) { model.ComponentClass = reflectedClass; model.IsEmbedded = false; } else { // an "embedded" component (ids only) model.ComponentClass = model.Owner.MappedClass; model.IsEmbedded = true; } foreach( XmlNode subnode in node.ChildNodes ) { //I am only concerned with elements that are from the nhibernate namespace if( subnode.NamespaceURI != Configuration.MappingSchemaXMLNS ) { continue; } string name = subnode.LocalName; //.Name; string propertyName = GetPropertyName( subnode ); string subpath = propertyName == null ? null : StringHelper.Qualify( path, propertyName ); CollectionType collectType = CollectionType.CollectionTypeFromString( name ); IValue value = null; if( collectType != null ) { Mapping.Collection collection = collectType.Create( subnode, className, subpath, model.Owner, mappings ); mappings.AddCollection( collection ); value = collection; } else if( "many-to-one".Equals( name ) || "key-many-to-one".Equals( name ) ) { value = new ManyToOne( model.Table ); BindManyToOne( subnode, ( ManyToOne ) value, subpath, isNullable, mappings ); } else if( "one-to-one".Equals( name ) ) { value = new OneToOne( model.Table, model.Owner.Identifier ); BindOneToOne( subnode, ( OneToOne ) value, isNullable, mappings ); } else if( "any".Equals( name ) ) { value = new Any( model.Table ); BindAny( subnode, ( Any ) value, isNullable, mappings ); } else if( "property".Equals( name ) || "key-property".Equals( name ) ) { value = new SimpleValue( model.Table ); BindSimpleValue( subnode, ( SimpleValue ) value, isNullable, subpath, mappings ); } else if( "component".Equals( name ) || "dynamic-component".Equals( name ) || "nested-composite-element".Equals( name ) ) { System.Type subreflectedClass = model.ComponentClass == null ? null : GetPropertyType( subnode, mappings, model.ComponentClass, propertyName ); value = ( model.Owner != null ) ? new Component( model.Owner ) : // a class component new Component( model.Table ); // a composite element BindComponent( subnode, ( Component ) value, subreflectedClass, className, subpath, isNullable, mappings ); } else if( "parent".Equals( name ) ) { model.ParentProperty = propertyName; } if( value != null ) { model.AddProperty( CreateProperty( value, propertyName, model.ComponentClass, subnode, mappings ) ); } } int span = model.PropertySpan; string[ ] names = new string[span]; IType[ ] types = new IType[span]; Cascades.CascadeStyle[ ] cascade = new Cascades.CascadeStyle[span]; OuterJoinFetchStrategy[ ] joinedFetch = new OuterJoinFetchStrategy[span]; int i = 0; foreach( Mapping.Property prop in model.PropertyCollection ) { if( prop.IsFormula ) { throw new MappingException( "properties of components may not be formulas: " + prop.Name ); } if( !prop.IsInsertable || !prop.IsUpdateable ) { throw new MappingException( "insert=\"false\", update=\"false\" not supported for properties of components: " + prop.Name ); } names[ i ] = prop.Name; types[ i ] = prop.Type; cascade[ i ] = prop.CascadeStyle; joinedFetch[ i ] = prop.Value.OuterJoinFetchSetting; i++; } IType componentType; if( model.IsDynamic ) { componentType = new DynamicComponentType( names, types, joinedFetch, cascade ); } else { IGetter[ ] getters = new IGetter[span]; ISetter[ ] setters = new ISetter[span]; bool foundCustomAccessor = false; i = 0; foreach( Mapping.Property prop in model.PropertyCollection ) { setters[ i ] = prop.GetSetter( model.ComponentClass ); getters[ i ] = prop.GetGetter( model.ComponentClass ); if( !prop.IsBasicPropertyAccessor ) { foundCustomAccessor = true; } i++; } componentType = new ComponentType( model.ComponentClass, names, getters, setters, foundCustomAccessor, types, joinedFetch, cascade, model.ParentProperty ); } model.Type = componentType; }
public AbstractCollectionPersister( Mapping.Collection collection, ISessionFactoryImplementor factory ) { this.factory = factory; dialect = factory.Dialect; //sqlExceptionConverter = factory.SQLExceptionConverter; collectionType = collection.CollectionType; role = collection.Role; ownerClass = collection.OwnerClass; Alias alias = new Alias( "__" ); sqlOrderByString = collection.OrderBy; hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate( sqlOrderByString, dialect ) : null; sqlWhereString = collection.Where; hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? Template.RenderWhereStringTemplate( sqlWhereString, dialect ) : null; hasOrphanDelete = collection.OrphanDelete; batchSize = collection.BatchSize; cache = collection.Cache; keyType = collection.Key.Type; int keySpan = collection.Key.ColumnSpan; keyColumnNames = new string[keySpan]; string[ ] keyAliases = new string[keySpan]; int k = 0; foreach( Column col in collection.Key.ColumnCollection ) { keyColumnNames[ k ] = col.GetQuotedName( dialect ); keyAliases[ k ] = col.Alias( dialect ); k++; } keyColumnAliases = alias.ToAliasStrings( keyAliases, dialect ); //unquotedKeyColumnNames = StringHelper.Unquote( keyColumnAliases ); ISet distinctColumns = new HashedSet(); CheckColumnDuplication( distinctColumns, collection.Key.ColumnCollection ); //isSet = collection.IsSet; //isSorted = collection.IsSorted; primitiveArray = collection.IsPrimitiveArray; array = collection.IsArray; IValue element = collection.Element; int elementSpan = element.ColumnSpan; ICollection iter = element.ColumnCollection; Table table = collection.CollectionTable; enableJoinedFetch = element.OuterJoinFetchSetting; elementType = element.Type; if( !collection.IsOneToMany ) { CheckColumnDuplication( distinctColumns, element.ColumnCollection ); } if( elementType.IsEntityType ) { elementPersister = factory.GetPersister( ( ( EntityType ) elementType ).AssociatedClass ); } else { elementPersister = null; } qualifiedTableName = table.GetQualifiedName( dialect, factory.DefaultSchema ); string[ ] aliases = new string[elementSpan]; elementColumnNames = new string[elementSpan]; int j = 0; foreach( Column col in iter ) { elementColumnNames[ j ] = col.GetQuotedName( dialect ); aliases[ j ] = col.Alias( dialect ); j++; } elementColumnAliases = alias.ToAliasStrings( aliases, dialect ); IType selectColumns; string[ ] selectType; hasIndex = collection.IsIndexed; if( hasIndex ) { IndexedCollection indexedCollection = ( IndexedCollection ) collection; indexType = indexedCollection.Index.Type; int indexSpan = indexedCollection.Index.ColumnSpan; indexColumnNames = new string[indexSpan]; string[ ] indexAliases = new string[indexSpan]; int i = 0; foreach( Column indexCol in indexedCollection.Index.ColumnCollection ) { indexAliases[ i ] = indexCol.Alias( dialect ); indexColumnNames[ i ] = indexCol.GetQuotedName( dialect ); i++; } selectType = indexColumnNames; selectColumns = indexType; indexColumnAliases = alias.ToAliasStrings( indexAliases, dialect ); CheckColumnDuplication( distinctColumns, indexedCollection.Index.ColumnCollection ); } else { indexType = null; indexColumnNames = null; indexColumnAliases = null; selectType = elementColumnNames; selectColumns = elementType; } hasIdentifier = collection.IsIdentified; if( hasIdentifier ) { if( collection.IsOneToMany ) { throw new MappingException( "one-to-many collections with identifiers are not supported." ); } IdentifierCollection idColl = ( IdentifierCollection ) collection; identifierType = idColl.Identifier.Type; Column col = null; foreach( Column column in idColl.Identifier.ColumnCollection ) { col = column; break; } identifierColumnName = col.GetQuotedName( dialect ); selectType = new string[ ] {identifierColumnName}; selectColumns = identifierType; identifierColumnAlias = alias.ToAliasString( col.Alias( dialect ), dialect ); unquotedIdentifierColumnName = identifierColumnAlias; identifierGenerator = idColl.Identifier.CreateIdentifierGenerator( dialect ); CheckColumnDuplication( distinctColumns, idColl.Identifier.ColumnCollection ); } else { identifierType = null; identifierColumnName = null; identifierColumnAlias = null; unquotedIdentifierColumnName = null; identifierGenerator = null; } rowSelectColumnNames = selectType; rowSelectType = selectColumns; sqlDeleteString = GenerateDeleteString(); sqlInsertRowString = GenerateInsertRowString(); sqlUpdateRowString = GenerateUpdateRowString(); sqlDeleteRowString = GenerateDeleteRowString(); isLazy = collection.IsLazy; isInverse = collection.IsInverse; if( collection.IsArray ) { elementClass = ( ( Array ) collection ).ElementClass; } else { // for non-arrays, we don't need to know the element class elementClass = null; } initializer = CreateCollectionInitializer( factory ); if( elementType.IsComponentType ) { elementPropertyMapping = new CompositeElementPropertyMapping( elementColumnNames, ( IAbstractComponentType ) elementType, factory ); } else if( !elementType.IsEntityType ) { elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType ); } else { IClassPersister persister = factory.GetPersister( ( ( EntityType ) elementType ).AssociatedClass ); // Not all classpersisters implement IPropertyMapping! if( persister is IPropertyMapping ) { elementPropertyMapping = ( IPropertyMapping ) persister; } else { elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType ); } } }
protected override JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[ ] foreignKeyColumns, ISessionFactoryImplementor factory ) { JoinType joinType = base.GetJoinType( type, config, path, table, foreignKeyColumns, factory ); // We can use an inner-join for the many-to-many if( joinType == JoinType.LeftOuterJoin && string.Empty.Equals( path ) ) { joinType = JoinType.InnerJoin; } return joinType; }
/// <summary> /// Does the mapping, and Hibernate default semantics, specify that /// this association should be fetched by outer joining /// </summary> /// <param name="config"></param> /// <param name="type"></param> /// <param name="factory"></param> /// <returns></returns> protected bool IsJoinedFetchEnabledByDefault( OuterJoinFetchStrategy config, IAssociationType type, ISessionFactoryImplementor factory ) { if ( !type.IsEntityType && !type.IsPersistentCollectionType ) { return false; } else { switch ( config ) { case OuterJoinFetchStrategy.Eager: return true; case OuterJoinFetchStrategy.Lazy: return false; case OuterJoinFetchStrategy.Auto: if ( !factory.IsOuterJoinedFetchEnabled ) { return false; } if ( type.IsEntityType ) { EntityType entityType = type as EntityType; IClassPersister persister = factory.GetPersister( entityType.AssociatedClass ); return !persister.HasProxy || ( entityType.IsOneToOne && ( (OneToOneType) entityType).IsNullable ); } else { return false; } default: throw new ArgumentOutOfRangeException( "config", config, "Unknown OJ strategy " + config.ToString() ); } } }
public AbstractCollectionPersister(Mapping.Collection collection, ISessionFactoryImplementor factory) { this.factory = factory; dialect = factory.Dialect; //sqlExceptionConverter = factory.SQLExceptionConverter; collectionType = collection.CollectionType; role = collection.Role; ownerClass = collection.OwnerClass; Alias alias = new Alias("__"); sqlOrderByString = collection.OrderBy; hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate(sqlOrderByString, dialect) : null; sqlWhereString = collection.Where; hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? Template.RenderWhereStringTemplate(sqlWhereString, dialect) : null; hasOrphanDelete = collection.OrphanDelete; batchSize = collection.BatchSize; cache = collection.Cache; keyType = collection.Key.Type; int keySpan = collection.Key.ColumnSpan; keyColumnNames = new string[keySpan]; string[] keyAliases = new string[keySpan]; int k = 0; foreach (Column col in collection.Key.ColumnCollection) { keyColumnNames[k] = col.GetQuotedName(dialect); keyAliases[k] = col.Alias(dialect); k++; } keyColumnAliases = alias.ToAliasStrings(keyAliases, dialect); //unquotedKeyColumnNames = StringHelper.Unquote( keyColumnAliases ); ISet distinctColumns = new HashedSet(); CheckColumnDuplication(distinctColumns, collection.Key.ColumnCollection); //isSet = collection.IsSet; //isSorted = collection.IsSorted; primitiveArray = collection.IsPrimitiveArray; array = collection.IsArray; IValue element = collection.Element; int elementSpan = element.ColumnSpan; ICollection iter = element.ColumnCollection; Table table = collection.CollectionTable; enableJoinedFetch = element.OuterJoinFetchSetting; elementType = element.Type; if (!collection.IsOneToMany) { CheckColumnDuplication(distinctColumns, element.ColumnCollection); } if (elementType.IsEntityType) { elementPersister = factory.GetPersister((( EntityType )elementType).AssociatedClass); } else { elementPersister = null; } qualifiedTableName = table.GetQualifiedName(dialect, factory.DefaultSchema); string[] aliases = new string[elementSpan]; elementColumnNames = new string[elementSpan]; int j = 0; foreach (Column col in iter) { elementColumnNames[j] = col.GetQuotedName(dialect); aliases[j] = col.Alias(dialect); j++; } elementColumnAliases = alias.ToAliasStrings(aliases, dialect); IType selectColumns; string[] selectType; hasIndex = collection.IsIndexed; if (hasIndex) { IndexedCollection indexedCollection = ( IndexedCollection )collection; indexType = indexedCollection.Index.Type; int indexSpan = indexedCollection.Index.ColumnSpan; indexColumnNames = new string[indexSpan]; string[] indexAliases = new string[indexSpan]; int i = 0; foreach (Column indexCol in indexedCollection.Index.ColumnCollection) { indexAliases[i] = indexCol.Alias(dialect); indexColumnNames[i] = indexCol.GetQuotedName(dialect); i++; } selectType = indexColumnNames; selectColumns = indexType; indexColumnAliases = alias.ToAliasStrings(indexAliases, dialect); CheckColumnDuplication(distinctColumns, indexedCollection.Index.ColumnCollection); } else { indexType = null; indexColumnNames = null; indexColumnAliases = null; selectType = elementColumnNames; selectColumns = elementType; } hasIdentifier = collection.IsIdentified; if (hasIdentifier) { if (collection.IsOneToMany) { throw new MappingException("one-to-many collections with identifiers are not supported."); } IdentifierCollection idColl = ( IdentifierCollection )collection; identifierType = idColl.Identifier.Type; Column col = null; foreach (Column column in idColl.Identifier.ColumnCollection) { col = column; break; } identifierColumnName = col.GetQuotedName(dialect); selectType = new string[] { identifierColumnName }; selectColumns = identifierType; identifierColumnAlias = alias.ToAliasString(col.Alias(dialect), dialect); unquotedIdentifierColumnName = identifierColumnAlias; identifierGenerator = idColl.Identifier.CreateIdentifierGenerator(dialect); CheckColumnDuplication(distinctColumns, idColl.Identifier.ColumnCollection); } else { identifierType = null; identifierColumnName = null; identifierColumnAlias = null; unquotedIdentifierColumnName = null; identifierGenerator = null; } rowSelectColumnNames = selectType; rowSelectType = selectColumns; sqlDeleteString = GenerateDeleteString(); sqlInsertRowString = GenerateInsertRowString(); sqlUpdateRowString = GenerateUpdateRowString(); sqlDeleteRowString = GenerateDeleteRowString(); isLazy = collection.IsLazy; isInverse = collection.IsInverse; if (collection.IsArray) { elementClass = (( Array )collection).ElementClass; } else { // for non-arrays, we don't need to know the element class elementClass = null; } initializer = CreateCollectionInitializer(factory); if (elementType.IsComponentType) { elementPropertyMapping = new CompositeElementPropertyMapping(elementColumnNames, ( IAbstractComponentType )elementType, factory); } else if (!elementType.IsEntityType) { elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType); } else { IClassPersister persister = factory.GetPersister((( EntityType )elementType).AssociatedClass); // Not all classpersisters implement IPropertyMapping! if (persister is IPropertyMapping) { elementPropertyMapping = ( IPropertyMapping )persister; } else { elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType); } } }
protected override JoinType GetJoinType( IAssociationType type, OuterJoinFetchStrategy config, string path, string table, string[] foreignKeyColumns, ISessionFactoryImplementor factory ) { if ( criteria.IsJoin( path ) ) { return JoinType.InnerJoin; } else { FetchMode fm = criteria.GetFetchMode( path ); //fm==null || - an Enum can't be null if( fm == FetchMode.Default ) { return base.GetJoinType( type, config, path, table, foreignKeyColumns, factory ); } else { return fm == FetchMode.Eager ? JoinType.LeftOuterJoin : JoinType.None; } } }