/// <summary> /// Initializes a new instance of <see cref="ScheduledEntityAction"/>. /// </summary> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> /// <param name="id">The identifier of the object.</param> /// <param name="instance">The actual object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> protected ScheduledEntityAction( ISessionImplementor session, object id, object instance, IClassPersister persister ) { this.session = session; this.id = id; this.persister = persister; this.instance = instance; }
/// <summary> /// Generate small message that can be used in traces and exception messages. /// </summary> /// <param name="persister">The <see cref="IClassPersister"/> for the class in question</param> /// <param name="id">The id</param> /// <returns>A descriptive <see cref="String" /> in the form <c>[FooBar#id]</c></returns> public static string InfoString(IClassPersister persister, object id) { StringBuilder s = new StringBuilder(); s.Append('['); if (persister == null) { s.Append("<null ClassPersister>"); } else { s.Append(persister.ClassName); } s.Append('#'); if (id == null) { s.Append("<null>"); } else { s.Append(id); } s.Append(']'); return(s.ToString()); }
/// <summary> /// Initializes a new instance of <see cref="ScheduledEntityAction"/>. /// </summary> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> /// <param name="id">The identifier of the object.</param> /// <param name="instance">The actual object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> protected ScheduledEntityAction(ISessionImplementor session, object id, object instance, IClassPersister persister) { this.session = session; this.id = id; this.persister = persister; this.instance = instance; }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="id"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> public object[] Assemble(object instance, object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) { if (subclass != persister.MappedClass) { throw new AssertionFailure("Tried to assemble a different subclass instance"); } return(Assemble(state, instance, id, persister, interceptor, session)); }
/// <summary> /// /// </summary> /// <param name="instance"></param> /// <param name="id"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> public object[ ] Assemble( object instance, object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session ) { if( subclass != persister.MappedClass ) { throw new AssertionFailure( "Tried to assemble a different subclass instance" ); } return Assemble( state, instance, id, persister, interceptor, session ); }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> private static object[ ] Disassemble( object obj, IClassPersister persister, ISessionImplementor session ) { object[ ] values = persister.GetPropertyValues( obj ); IType[ ] propertyTypes = persister.PropertyTypes; for( int i = 0; i < values.Length; i++ ) { values[ i ] = propertyTypes[ i ].Disassemble( values[ i ], session ); } return values; }
public override void Process(object obj, IClassPersister persister) { object[] values = persister.GetPropertyValues(obj); IType[] types = persister.PropertyTypes; ProcessValues(values, types); if (IsSubstitutionRequired) { persister.SetPropertyValues(obj, values); } }
public BatchingEntityLoader( IClassPersister persister, int batchSize, Loader batchLoader, int smallBatchSize, Loader smallBatchLoader, Loader nonBatchLoader ) { this.batchLoader = batchLoader; this.nonBatchLoader = nonBatchLoader; this.batchSize = batchSize; this.persister = persister; this.smallBatchLoader = smallBatchLoader; this.smallBatchSize = smallBatchSize; idType = persister.IdentifierType; }
/// <summary> /// /// </summary> /// <param name="theClass"></param> /// <returns></returns> public IClassPersister GetPersister(System.Type theClass) { IClassPersister result = classPersisters[theClass] as IClassPersister; if (result == null) { throw new MappingException("Unknown entity class: " + theClass.FullName); } return(result); }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> private static object[] Disassemble(object obj, IClassPersister persister, ISessionImplementor session) { object[] values = persister.GetPropertyValues(obj); IType[] propertyTypes = persister.PropertyTypes; for (int i = 0; i < values.Length; i++) { values[i] = propertyTypes[i].Disassemble(values[i], session); } return(values); }
/// <summary> /// Initializes a new instance of <see cref="ScheduledUpdate"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="fields">An array of objects that contains the value of each Property.</param> /// <param name="dirtyProperties">An array that contains the indexes of the dirty Properties.</param> /// <param name="oldFields"></param> /// <param name="lastVersion">The current version of the object.</param> /// <param name="nextVersion">The version the object should be after update.</param> /// <param name="instance">The actual object instance.</param> /// <param name="updatedState">A deep copy of the <c>fields</c> object array.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledUpdate( object id, object[ ] fields, int[ ] dirtyProperties, object[ ] oldFields, object lastVersion, object nextVersion, object instance, object[ ] updatedState, IClassPersister persister, ISessionImplementor session ) : base( session, id, instance, persister ) { this.fields = fields; this.oldFields = oldFields; this.lastVersion = lastVersion; this.nextVersion = nextVersion; this.dirtyFields = dirtyProperties; this.updatedState = updatedState; }
public BatchingEntityLoader(IClassPersister persister, int batchSize, Loader batchLoader, int smallBatchSize, Loader smallBatchLoader, Loader nonBatchLoader) { this.batchLoader = batchLoader; this.nonBatchLoader = nonBatchLoader; this.batchSize = batchSize; this.persister = persister; this.smallBatchLoader = smallBatchLoader; this.smallBatchSize = smallBatchSize; idType = persister.IdentifierType; }
void IDeserializationCallback.OnDeserialization(object sender) { try { persister = session.GetPersister(instance); } catch (MappingException e) { throw new IOException("Unable to resolve class persister on deserialization", e); } }
public static object GetIdentifier( object obj, IClassPersister persister ) { if( obj is INHibernateProxy ) { INHibernateProxy proxy = ( INHibernateProxy ) obj; LazyInitializer li = GetLazyInitializer( proxy ); return li.Identifier; } else { return persister.GetIdentifier( obj ); } }
public void Evict(System.Type persistentClass, object id) { IClassPersister p = GetPersister(persistentClass); if (p.HasCache) { if (log.IsDebugEnabled) { log.Debug("evicting second-level cache: " + MessageHelper.InfoString(p, id)); } p.Cache.Remove(id); } }
public void Evict(System.Type persistentClass) { IClassPersister p = GetPersister(persistentClass); if (p.HasCache) { if (log.IsDebugEnabled) { log.Debug("evicting second-level cache: " + p.ClassName); } p.Cache.Clear(); } }
public static object GetIdentifier(object obj, IClassPersister persister) { if (obj is INHibernateProxy) { INHibernateProxy proxy = ( INHibernateProxy )obj; LazyInitializer li = GetLazyInitializer(proxy); return(li.Identifier); } else { return(persister.GetIdentifier(obj)); } }
/// <summary> /// Initializes a new instance of EntityEntry. /// </summary> /// <param name="status">The current <see cref="Status"/> of the Entity.</param> /// <param name="loadedState">The snapshot of the Entity's state when it was loaded.</param> /// <param name="id">The identifier of the Entity in the database.</param> /// <param name="version">The version of the Entity.</param> /// <param name="lockMode">The <see cref="LockMode"/> for the Entity.</param> /// <param name="existsInDatabase">A boolean indicating if the Entity exists in the database.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for this Entity.</param> /// <param name="disableVersionIncrement"></param> public EntityEntry(Status status, object[] loadedState, object id, object version, LockMode lockMode, bool existsInDatabase, IClassPersister persister, bool disableVersionIncrement ) { this.status = status; this.loadedState = loadedState; this.id = id; this.existsInDatabase = existsInDatabase; this.version = version; this.lockMode = lockMode; this.isBeingReplicated = disableVersionIncrement; this.persister = persister; if ( persister != null ) { className = persister.ClassName; } }
/// <summary> /// Initializes a new instance of EntityEntry. /// </summary> /// <param name="status">The current <see cref="Status"/> of the Entity.</param> /// <param name="loadedState">The snapshot of the Entity's state when it was loaded.</param> /// <param name="id">The identifier of the Entity in the database.</param> /// <param name="version">The version of the Entity.</param> /// <param name="lockMode">The <see cref="LockMode"/> for the Entity.</param> /// <param name="existsInDatabase">A boolean indicating if the Entity exists in the database.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for this Entity.</param> /// <param name="disableVersionIncrement"></param> public EntityEntry(Status status, object[] loadedState, object id, object version, LockMode lockMode, bool existsInDatabase, IClassPersister persister, bool disableVersionIncrement) { this.status = status; this.loadedState = loadedState; this.id = id; this.existsInDatabase = existsInDatabase; this.version = version; this.lockMode = lockMode; this.isBeingReplicated = disableVersionIncrement; this.persister = persister; if (persister != null) { className = persister.ClassName; } }
public IClassPersister GetPersister(string className, bool throwIfNotFound) { // TODO: H2.1 has the code below, an equivalent for .NET would be useful //if( className.StartsWith( "[" ) ) //{ // throw new MappingException( "No persister for array result, likely a broken query" ); //} IClassPersister result = classPersistersByName[className] as IClassPersister; if (result == null && throwIfNotFound) { throw new MappingException("No persister for: " + className); } return(result); }
public override string ToString(object value, ISessionFactoryImplementor factory) { IClassPersister persister = factory.GetPersister(associatedClass); if (value == null) { return("null"); } StringBuilder result = new StringBuilder(); result.Append(StringHelper.Unqualify(NHibernateProxyHelper.GetClass(value).FullName)); if (persister.HasIdentifierProperty) { result.Append('#') .Append(persister.IdentifierType.ToString(NHibernateProxyHelper.GetIdentifier(value, persister), factory)); } return(result.ToString()); }
/// <summary> /// /// </summary> /// <param name="values"></param> /// <param name="result"></param> /// <param name="id"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> private static object[ ] Assemble( object[ ] values, object result, object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session ) { IType[ ] propertyTypes = persister.PropertyTypes; object[ ] assembledProps = new object[propertyTypes.Length]; for( int i = 0; i < values.Length; i++ ) { assembledProps[ i ] = propertyTypes[ i ].Assemble( values[ i ], session, result ); } interceptor.OnLoad( result, id, assembledProps, persister.PropertyNames, propertyTypes ); persister.SetPropertyValues( result, assembledProps ); if( persister.ImplementsLifecycle ) { ( ( ILifecycle ) result ).OnLoad( session, id ); } return assembledProps; }
/// <summary> /// /// </summary> /// <param name="values"></param> /// <param name="result"></param> /// <param name="id"></param> /// <param name="persister"></param> /// <param name="session"></param> /// <returns></returns> private static object[] Assemble(object[] values, object result, object id, IClassPersister persister, IInterceptor interceptor, ISessionImplementor session) { IType[] propertyTypes = persister.PropertyTypes; object[] assembledProps = new object[propertyTypes.Length]; for (int i = 0; i < values.Length; i++) { assembledProps[i] = propertyTypes[i].Assemble(values[i], session, result); } interceptor.OnLoad(result, id, assembledProps, persister.PropertyNames, propertyTypes); persister.SetPropertyValues(result, assembledProps); if (persister.ImplementsLifecycle) { (( ILifecycle )result).OnLoad(session, id); } return(assembledProps); }
public override void Execute() { IClassPersister persister = Persister; ISessionImplementor session = Session; object obj = Instance; // Don't need to lock the cache here, since if someone // else inserted the same pk first, the insert would fail. generatedId = persister.Insert(state, obj, session); // TODO: This bit has to be called after all the cascades /* * if ( persister.HasCache && !persister.IsCacheInvalidationRequired ) * { * cacheEntry = new CacheEntry( obj, persister, session ); * persister.Cache.Put( generatedId, cacheEntry, 0 ); * } */ }
/// <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()); } } }
/// <summary> /// Cascade an action from the parent object to all its children. /// </summary> /// <param name="session"></param> /// <param name="persister"></param> /// <param name="parent"></param> /// <param name="action"></param> /// <param name="cascadeTo"></param> /// <param name="anything"></param> public static void Cascade(ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo, object anything) { if (persister.HasCascades) { if (log.IsDebugEnabled) { log.Debug("processing cascades for: " + persister.ClassName); } IType[] types = persister.PropertyTypes; CascadeStyle[] cascadeStyles = persister.PropertyCascadeStyles; for (int i = 0; i < types.Length; i++) { CascadeStyle style = cascadeStyles[i]; if (style.DoCascade(action)) { Cascade(session, persister.GetPropertyValue(parent, i), types[i], action, style, cascadeTo, anything); } } if (log.IsDebugEnabled) { log.Debug("done processing cascades for: " + persister.ClassName); } } }
/// <summary> /// Add the "hydrated state" (an array) of an uninitialized entity to the session. /// We don't try to resolve any associations yet, because there might be other entities /// waiting to be read from the ADO datareader we are currently processing /// </summary> /// <param name="persister"></param> /// <param name="id"></param> /// <param name="values"></param> /// <param name="obj"></param> /// <param name="lockMode"></param> public void PostHydrate( IClassPersister persister, object id, object[ ] values, object obj, LockMode lockMode ) { //persister.SetIdentifier( obj, id ); object version = Versioning.GetVersion( values, persister ); AddEntry( obj, Status.Loading, values, id, version, lockMode, true, persister, false ); if( log.IsDebugEnabled && version != null ) { log.Debug( "Version: " + version ); } }
private IClassPersister GetClassPersister( System.Type theClass ) { if( lastClass != theClass ) { lastResultForClass = factory.GetPersister( theClass ); lastClass = theClass; } return lastResultForClass; }
/// <summary> /// Initializes a new instance of <see cref="ScheduledDeletion"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="version">The version of the object being deleted.</param> /// <param name="instance">The actual object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledDeletion( object id, object version, object instance, IClassPersister persister, ISessionImplementor session ) : base( session, id, instance, persister ) { this.version = version; }
/// <summary> /// Initializes a new instance of <see cref="ScheduledInsertion"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="state">An object array that contains the state of the object being inserted.</param> /// <param name="instance">The actual object instance.</param> /// <param name="version">The version of the object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledInsertion(object id, object[] state, object instance, object version, IClassPersister persister, ISessionImplementor session) : base(session, id, instance, persister) { this.state = state; this.version = version; }
/// <summary> /// /// </summary> /// <param name="state"></param> /// <param name="instance"></param> /// <param name="persister"></param> /// <param name="session"></param> public ScheduledIdentityInsertion( object[] state, object instance, IClassPersister persister, ISessionImplementor session ) : base( session, null, instance, persister ) { this.state = state; }
/// <summary> /// Initializes a new instance of <see cref="ScheduledDeletion"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="version">The version of the object being deleted.</param> /// <param name="instance">The actual object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledDeletion(object id, object version, object instance, IClassPersister persister, ISessionImplementor session) : base(session, id, instance, persister) { this.version = version; }
/// <summary> /// Initializes a new instance of <see cref="ScheduledUpdate"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="fields">An array of objects that contains the value of each Property.</param> /// <param name="dirtyProperties">An array that contains the indexes of the dirty Properties.</param> /// <param name="oldFields"></param> /// <param name="lastVersion">The current version of the object.</param> /// <param name="nextVersion">The version the object should be after update.</param> /// <param name="instance">The actual object instance.</param> /// <param name="updatedState">A deep copy of the <c>fields</c> object array.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledUpdate(object id, object[] fields, int[] dirtyProperties, object[] oldFields, object lastVersion, object nextVersion, object instance, object[] updatedState, IClassPersister persister, ISessionImplementor session) : base(session, id, instance, persister) { this.fields = fields; this.oldFields = oldFields; this.lastVersion = lastVersion; this.nextVersion = nextVersion; this.dirtyFields = dirtyProperties; this.updatedState = updatedState; }
private EntityEntry AddEntry( object obj, Status status, object[ ] loadedState, object id, object version, LockMode lockMode, bool existsInDatabase, IClassPersister persister, bool disableVersionIncrement ) { EntityEntry e = new EntityEntry( status, loadedState, id, version, lockMode, existsInDatabase, persister, disableVersionIncrement ); entityEntries[ obj ] = e; return e; }
private object DoSave( object obj, object id, IClassPersister persister, bool useIdentityColumn, Cascades.CascadingAction cascadeAction, object anything ) { if( log.IsDebugEnabled ) { log.Debug( "saving " + MessageHelper.InfoString( persister, id ) ); } Key key; if( useIdentityColumn ) { // if the id is generated by the database, we assign the key later key = null; } else { key = new Key( id, persister ); object old = GetEntity( key ); if( old != null ) { EntityEntry e = GetEntry( old ); if( e.Status == Status.Deleted ) { ForceFlush( e ); } else { throw new NonUniqueObjectException( id, persister.MappedClass ); } } persister.SetIdentifier( obj, id ); } // Sub-insertions should occur before containing insertsion so // Try to do the callback not if( persister.ImplementsLifecycle ) { log.Debug( "calling OnSave()" ); if( ( ( ILifecycle ) obj ).OnSave( this ) == LifecycleVeto.Veto ) { log.Debug( "insertion vetoed by OnSave()" ); return id; } } return DoSave( obj, key, persister, false, useIdentityColumn, cascadeAction, anything ); }
private object DoSave( object theObj, Key key, IClassPersister persister, bool replicate, bool useIdentityColumn, Cascades.CascadingAction cascadeAction, object anything ) { if( persister.ImplementsValidatable ) { ( ( IValidatable ) theObj ).Validate(); } object id; if( useIdentityColumn ) { id = null; ExecuteInserts(); } else { id = key.Identifier; } // Put a placeholder in entries, so we don't recurse back to try and Save() the // same object again. QUESTION: Should this be done before OnSave() is called? // likewise, should it be done before OnUpdate()? AddEntry( theObj, Status.Saving, null, id, null, LockMode.Write, useIdentityColumn, persister, false ); // okay if id is null here // cascade-save to many-to-one BEFORE the parent is saved cascading++; try { Cascades.Cascade( this, persister, theObj, cascadeAction, CascadePoint.CascadeBeforeInsertAfterDelete, anything ); } finally { cascading--; } object[ ] values = persister.GetPropertyValues( theObj ); IType[ ] types = persister.PropertyTypes; bool substitute = false; if( !replicate ) { substitute = interceptor.OnSave( theObj, id, values, persister.PropertyNames, types ); // Keep the existing version number in the case of replicate! if( persister.IsVersioned ) { // IsUnsavedVersion bit below is NHibernate-specific substitute = Versioning.SeedVersion( values, persister.VersionProperty, persister.VersionType, persister.IsUnsavedVersion( values ) ) || substitute; } } if( persister.HasCollections ) { // TODO: make OnReplicateVisitor extend WrapVisitor if( replicate ) { OnReplicateVisitor visitor = new OnReplicateVisitor( this, id ); visitor.ProcessValues( values, types ); } WrapVisitor visitor2 = new WrapVisitor( this ); // substitutes into values by side-effect visitor2.ProcessValues( values, types ); substitute = substitute || visitor2.IsSubstitutionRequired; } if( substitute ) { persister.SetPropertyValues( theObj, values ); } TypeFactory.DeepCopy( values, types, persister.PropertyUpdateability, values ); NullifyTransientReferences( values, types, useIdentityColumn, theObj ); CheckNullability( values, persister, false ); if( useIdentityColumn ) { ScheduledIdentityInsertion insert = new ScheduledIdentityInsertion( values, theObj, persister, this ); Execute( insert ); id = insert.GeneratedId; persister.SetIdentifier( theObj, id ); key = new Key( id, persister ); CheckUniqueness( key, theObj ); } object version = Versioning.GetVersion( values, persister ); AddEntity( key, theObj ); AddEntry( theObj, Status.Loaded, values, id, version, LockMode.Write, useIdentityColumn, persister, replicate ); nonExists.Remove( key ); if( !useIdentityColumn ) { insertions.Add( new ScheduledInsertion( id, values, theObj, version, persister, this ) ); } // cascade-save to collections AFTER the collection owner was saved cascading++; try { Cascades.Cascade( this, persister, theObj, cascadeAction, CascadePoint.CascadeAfterInsertBeforeDelete, anything ); } finally { cascading--; } return id; }
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); } } }
/// <summary> /// /// </summary> /// <param name="cfg"></param> /// <param name="settings"></param> public SessionFactoryImpl(Configuration cfg, Settings settings) { log.Info("building session factory"); this.properties = cfg.Properties; this.interceptor = cfg.Interceptor; this.settings = settings; if (log.IsDebugEnabled) { log.Debug("instantiating session factory with properties: " + CollectionPrinter.ToString(properties)); } // Persisters: classPersisters = new Hashtable(); classPersistersByName = new Hashtable(); IDictionary classMeta = new Hashtable(); foreach (PersistentClass model in cfg.ClassMappings) { IClassPersister cp = PersisterFactory.CreateClassPersister(model, this); classPersisters[model.MappedClass] = cp; // Adds the "Namespace.ClassName" (FullClassname) as a lookup to get to the Persiter. // Most of the internals of NHibernate use this method to get to the Persister since // Model.Name is used in so many places. It would be nice to fix it up to be Model.TypeName // instead of just FullClassname classPersistersByName[model.Name] = cp; // Add in the AssemblyQualifiedName (includes version) as a lookup to get to the Persister. // In HQL the Imports are used to get from the Classname to the Persister. The // Imports provide the ability to jump from the Classname to the AssemblyQualifiedName. classPersistersByName[model.MappedClass.AssemblyQualifiedName] = cp; classMeta[model.MappedClass] = cp.ClassMetadata; } classMetadata = new Hashtable(classMeta); collectionPersisters = new Hashtable(); foreach (Mapping.Collection map in cfg.CollectionMappings) { collectionPersisters[map.Role] = PersisterFactory .CreateCollectionPersister(map, this) .CollectionMetadata; } collectionMetadata = new Hashtable(collectionPersisters); // after *all* persisters are registered foreach (IClassPersister persister in classPersisters.Values) { // TODO: H2.1 doesn't pass this to PostInstantiate persister.PostInstantiate(this); } //TODO: // For databinding: //templates = XMLDatabinder.GetOutputStyleSheetTemplates( properties ); // serialization info name = settings.SessionFactoryName; try { uuid = ( string )UuidGenerator.Generate(null, null); } catch (Exception) { throw new AssertionFailure("could not generate UUID"); } SessionFactoryObjectFactory.AddInstance(uuid, name, this, properties); // Named queries: // TODO: precompile and cache named queries namedQueries = new Hashtable(cfg.NamedQueries); namedSqlQueries = new Hashtable(cfg.NamedSQLQueries.Count); foreach (DictionaryEntry de in cfg.NamedSQLQueries) { NamedSQLQuery nsq = ( NamedSQLQuery )de.Value; namedSqlQueries[de.Key] = new InternalNamedSQLQuery(nsq.QueryString, nsq.ReturnAliases, nsq.ReturnClasses, nsq.SynchronizedTables); } imports = new Hashtable(cfg.Imports); log.Debug("Instantiated session factory"); if (settings.IsAutoCreateSchema) { new SchemaExport(cfg).Create(false, true); } /* * if ( settings.IsAutoUpdateSchema ) * { * new SchemaUpdate( cfg ).Execute( false, true ); * } */ if (settings.IsAutoDropSchema) { schemaExport = new SchemaExport(cfg); } // Obtaining TransactionManager - not ported from H2.1 if (settings.IsQueryCacheEnabled) { updateTimestampsCache = new UpdateTimestampsCache(settings.CacheProvider, properties); queryCache = settings.QueryCacheFactory .GetQueryCache(null, settings.CacheProvider, updateTimestampsCache, properties); queryCaches = Hashtable.Synchronized(new Hashtable()); } else { updateTimestampsCache = null; queryCache = null; queryCaches = null; } }
/// <summary> /// Initializes a new instance of <see cref="ScheduledInsertion"/>. /// </summary> /// <param name="id">The identifier of the object.</param> /// <param name="state">An object array that contains the state of the object being inserted.</param> /// <param name="instance">The actual object instance.</param> /// <param name="version">The version of the object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledInsertion( object id, object[ ] state, object instance, object version, IClassPersister persister, ISessionImplementor session ) : base( session, id, instance, persister ) { this.state = state; this.version = version; }
/// <summary> /// Evict collections from the factory-level cache /// </summary> /// <param name="persister"></param> /// <param name="id"></param> private void EvictCachedCollections( IClassPersister persister, object id ) { EvictCachedCollections( persister.PropertyTypes, id ); }
/// <summary> /// /// </summary> /// <param name="state"></param> /// <param name="instance"></param> /// <param name="persister"></param> /// <param name="session"></param> public ScheduledIdentityInsertion(object[] state, object instance, IClassPersister persister, ISessionImplementor session) : base(session, null, instance, persister) { this.state = state; }
private object GetNextVersion( IClassPersister persister, object[ ] values, EntityEntry entry ) { if( persister.IsVersioned ) { if( entry.IsBeingReplicated ) { return Versioning.GetVersion( values, persister ); } else { Object nextVersion = entry.Status == Status.Deleted ? entry.Version : Versioning.Increment( entry.Version, persister.VersionType ); Versioning.SetVersion( values, nextVersion, persister ); return nextVersion; } } else { return null; } }
private static void CheckId( object obj, IClassPersister persister, object id ) { // make sure user didn't mangle the id if( persister.HasIdentifierPropertyOrEmbeddedCompositeIdentifier ) { object oid = persister.GetIdentifier( obj ); if( id == null ) { throw new AssertionFailure( "null id in entry (don't flush the Session after an exception occurs)" ); } if( !id.Equals( oid ) ) { throw new HibernateException( string.Format( "identifier of an instance of {0} altered from {1} ({2}) to {3} ({4})", persister.ClassName, id, id.GetType(), oid, oid.GetType() ) ); } } }
/// <summary> /// Walk the tree starting from the given entity. /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> public virtual void Process(object obj, IClassPersister persister) { ProcessValues( persister.GetPropertyValues(obj), persister.PropertyTypes); }
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 ); } } }
/// <summary> /// Grab the existing proxy for an instance, if one exists. /// (otherwise return the instance) /// </summary> /// <param name="persister"></param> /// <param name="key"></param> /// <param name="impl"></param> /// <returns></returns> public object ProxyFor( IClassPersister persister, Key key, object impl ) { if( !persister.HasProxy || key == null ) { return impl; } object proxy = proxiesByKey[ key ]; if( proxy != null ) { return NarrowProxy( proxy, persister, key, impl ); } else { return impl; } }
/// <summary> /// Cascade an action from the parent object to all its children. /// </summary> /// <param name="session"></param> /// <param name="persister"></param> /// <param name="parent"></param> /// <param name="action"></param> /// <param name="cascadeTo"></param> /// <param name="anything"></param> public static void Cascade( ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo, object anything ) { if( persister.HasCascades ) { if( log.IsDebugEnabled ) { log.Debug( "processing cascades for: " + persister.ClassName ); } IType[ ] types = persister.PropertyTypes; CascadeStyle[ ] cascadeStyles = persister.PropertyCascadeStyles; for( int i = 0; i < types.Length; i++ ) { CascadeStyle style = cascadeStyles[ i ]; if( style.DoCascade( action ) ) { Cascade( session, persister.GetPropertyValue( parent, i ), types[ i ], action, style, cascadeTo, anything ); } } if( log.IsDebugEnabled ) { log.Debug( "done processing cascades for: " + persister.ClassName ); } } }
/// <summary> /// Construct a unique identifier for an entity class instace /// </summary> /// <param name="id"></param> /// <param name="p"></param> public Key( object id, IClassPersister p ) : this( id, p.IdentifierType, p.IdentifierSpace, p.MappedClass, p.IsBatchLoadable ) { }
private void DoEvict( IClassPersister persister, object obj ) { if( log.IsDebugEnabled ) { log.Debug( "evicting " + MessageHelper.InfoString( persister ) ); } //remove all collections for the entity from the session-level cache if( persister.HasCollections ) { new EvictVisitor( this ).Process( obj, persister ); } Cascades.Cascade( this, persister, obj, Cascades.CascadingAction.ActionEvict, CascadePoint.CascadeOnEvict ); }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> /// <param name="session"></param> public CacheEntry(object obj, IClassPersister persister, ISessionImplementor session) { state = Disassemble(obj, persister, session); subclass = obj.GetType(); }
/// <summary> /// /// </summary> /// <param name="session"></param> /// <param name="persister"></param> /// <param name="parent"></param> /// <param name="action"></param> /// <param name="cascadeTo"></param> public static void Cascade(ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo) { Cascade(session, persister, parent, action, cascadeTo, null); }
private object AssembleCacheEntry( CacheEntry entry, object id, IClassPersister persister, object optionalObject ) { if( log.IsDebugEnabled ) { log.Debug( "resolved object in second-level cache " + MessageHelper.InfoString( persister, id ) ); } IClassPersister subclassPersister = GetClassPersister( entry.Subclass ); object result = optionalObject != null ? optionalObject : Instantiate( subclassPersister, id ); AddEntry( result, Status.Loading, null, id, null, LockMode.None, true, subclassPersister, false ); AddEntity( new Key( id, persister ), result ); IType[ ] types = subclassPersister.PropertyTypes; object[ ] values = entry.Assemble( result, id, subclassPersister, interceptor, this ); // intializes result by side-effect TypeFactory.DeepCopy( values, types, subclassPersister.PropertyUpdateability, values ); object version = Versioning.GetVersion( values, subclassPersister ); if( log.IsDebugEnabled ) { log.Debug( "Cached Version: " + version ); } AddEntry( result, Status.Loaded, values, id, version, LockMode.None, true, subclassPersister, false ); InitializeNonLazyCollections(); // upgrade lock if necessary; //Lock( result, lockMode ); return result; }
/// <summary> /// Get the version number of the given instance state snapshot /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for persisting the values of the <c>fields</c> parameter.</param> /// <returns> /// The value of the version contained in the <c>fields</c> parameter or null if the /// Entity is not versioned. /// </returns> public static object GetVersion(object[] fields, IClassPersister persister) { return(persister.IsVersioned ? GetVersion(fields, persister.VersionProperty, persister.VersionType) : null); }
public override void Process(object obj, IClassPersister persister) { object[] values = persister.GetPropertyValues( obj ); IType[] types = persister.PropertyTypes; ProcessValues( values, types ); if( IsSubstitutionRequired ) { persister.SetPropertyValues( obj, values ); } }
/// <summary> /// /// </summary> /// <param name="session"></param> /// <param name="persister"></param> /// <param name="parent"></param> /// <param name="action"></param> /// <param name="cascadeTo"></param> public static void Cascade( ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo ) { Cascade( session, persister, parent, action, cascadeTo, null ); }
/// <summary> /// Walk the tree starting from the given entity. /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> public virtual void Process(object obj, IClassPersister persister) { ProcessValues( persister.GetPropertyValues( obj ), persister.PropertyTypes ); }
private bool IsUpdateNecessary( IClassPersister persister, bool cannotDirtyCheck, Status status, int[ ] dirtyProperties, object[ ] values, IType[ ] types ) { if( !persister.IsMutable ) { return false; } if( cannotDirtyCheck ) { return true; } if( dirtyProperties != null && dirtyProperties.Length != 0 ) { return true; } if( status == Status.Loaded && persister.IsVersioned && persister.HasCollections ) { DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor( this ); visitor.ProcessValues( values, types ); return visitor.WasDirtyCollectionFound; } else { return false; } }
/// <summary> /// Construct a unique identifier for an entity class instace /// </summary> /// <param name="id"></param> /// <param name="p"></param> public Key(object id, IClassPersister p) : this(id, p.IdentifierType, p.IdentifierSpace, p.MappedClass, p.IsBatchLoadable) { }
/// <summary> /// Set the version number of the given instance state snapshot /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="version">The value the version should be set to in the <c>fields</c> parameter.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for persisting the values of the <c>fields</c> parameter.</param> public static void SetVersion(object[] fields, object version, IClassPersister persister) { SetVersion(fields, version, persister.VersionProperty, persister.VersionType); }