/// <summary> /// 生成主键 /// </summary> /// <param name="session"></param> /// <param name="obj"></param> /// <returns></returns> public object Generate(ISessionImplementor session, object obj) { TypedEntityMetadata entityInfo = TypedEntityMetadata.GenerateEntityInfo(session.Factory, obj.GetType()); return PrimaryMaxIdGenerator.GetMaxId(entityInfo.TableName, entityInfo.IdColumnName, entityInfo.IdLength, PrimaryMaxIdGenerator.GetIdYearMonth()).ToString(); }
public override INHibernateProxy GetProxy(object id, ISessionImplementor session) { // If it is not a proxy for a class do what you usually did. if (!IsClassProxy) return base.GetProxy(id, session); try { LazyInitializer initializer = new DataBindingInterceptor(EntityName, PersistentClass, id, GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, session); // Add to the list of the interfaces that the proxy class will support the INotifyPropertyChanged interface. // This is only needed in the case when we need to cast our proxy object as INotifyPropertyChanged interface. ArrayList list = new ArrayList(Interfaces); list.Add(typeof(INotifyPropertyChanged)); System.Type[] interfaces = (System.Type[])list.ToArray(typeof(System.Type)); //We create the proxy object generatedProxy = DefaultProxyGenerator.CreateClassProxy(PersistentClass, interfaces, initializer); initializer._constructed = true; return (INHibernateProxy)generatedProxy; } catch (Exception e) { Logger.Error("Creating a proxy instance failed", e); throw new HibernateException("Creating a proxy instance failed", e); } }
public override object Assemble(object cached, ISessionImplementor session, object owner) { byte[] identifier = cached as byte[]; if (identifier == null) return null; IExternalBlobConnection conn = GetExternalBlobConnection(session); return CreateLobInstance(conn, identifier); }
public object Load(object id, object optionalObject, ISessionImplementor session) { object[] batch = session.PersistenceContext.BatchFetchQueue.GetEntityBatch(persister, id, batchSizes[0]); for (int i = 0; i < batchSizes.Length - 1; i++) { int smallBatchSize = batchSizes[i]; if (batch[smallBatchSize - 1] != null) { object[] smallBatch = new object[smallBatchSize]; Array.Copy(batch, 0, smallBatch, 0, smallBatchSize); IList results = loaders[i].LoadEntityBatch( session, smallBatch, idType, optionalObject, persister.EntityName, id, persister); return GetObjectFromList(results, id, session); //EARLY EXIT } } return ((IUniqueEntityLoader) loaders[batchSizes.Length - 1]).Load(id, optionalObject, session); }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, Iesi.Collections.Generic.ISet<string> spaces, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug("checking cached query results in region: " + regionName); } IList cacheable = (IList) queryCache.Get(key); if (cacheable == null) { log.Debug("query results were not found in cache"); return null; } IList result = new ArrayList(cacheable.Count - 1); long timestamp = (long) cacheable[0]; log.Debug("Checking query spaces for up-to-dateness [" + spaces + "]"); if (! IsUpToDate(spaces, timestamp)) { log.Debug("cached query results were not up to date"); return null; } log.Debug("returning cached query results"); for (int i = 1; i < cacheable.Count; i++) { if (returnTypes.Length == 1) { result.Add(returnTypes[0].Assemble(cacheable[i], session, null)); } else { result.Add(TypeFactory.Assemble((object[]) cacheable[i], returnTypes, session, null)); } } return result; }
public EntityIdentityInsertAction(object[] state, object instance, IEntityPersister persister, ISessionImplementor session, bool isDelayed) : base(session, null, instance, persister) { this.state = state; this.isDelayed = isDelayed; delayedEntityKey = this.isDelayed ? GenerateDelayedEntityKey() : null; }
public object Load( ISessionImplementor session, object id, object optionalObject, object optionalId ) { IList list = LoadEntity( session, id, uniqueKeyType, optionalObject, optionalId ); if( list.Count == 1 ) { return list[ 0 ]; } else if( list.Count == 0 ) { return null; } else { if ( CollectionOwner > -1 ) { return list[ 0 ]; } else { throw new HibernateException( "More than one row with the given identifier was found: " + id + ", for class: " + Persister.ClassName ); } } }
protected override Object GetResultColumnOrRow( Object[ ] row, IDataReader rs, ISessionImplementor session ) { return row[ 0 ]; }
public bool Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session) { if (isNaturalKeyLookup && result.Count == 0) return false; long ts = session.Timestamp; if (Log.IsDebugEnabled) Log.DebugFormat("caching query results in region: '{0}'; {1}", _regionName, key); IList cacheable = new List<object>(result.Count + 1) {ts}; for (int i = 0; i < result.Count; i++) { if (returnTypes.Length == 1 && !key.HasResultTransformer) { cacheable.Add(returnTypes[0].Disassemble(result[i], session, null)); } else { cacheable.Add(TypeHelper.Disassemble((object[]) result[i], returnTypes, null, session, null)); } } _queryCache.Put(key, cacheable); return true; }
/// <summary> /// Generate an <see cref="Int16"/>, <see cref="Int32"/>, or <see cref="Int64"/> /// for the identifier by using a database sequence. /// </summary> /// <param name="session">The <see cref="ISessionImplementor"/> this id is being generated in.</param> /// <param name="obj">The entity for which the id is being generated.</param> /// <returns>The new identifier as a <see cref="Int16"/>, <see cref="Int32"/>, or <see cref="Int64"/>.</returns> public virtual object Generate( ISessionImplementor session, object obj ) { IDbCommand cmd = session.Batcher.PrepareCommand( new SqlString( sql ) ); IDataReader reader = null; try { reader = session.Batcher.ExecuteReader( cmd ); object result = null; reader.Read(); result = IdentifierGeneratorFactory.Get( reader, returnClass ); log.Debug( "sequence ID generated: " + result ); return result; } // TODO: change to SQLException catch( Exception e ) { // TODO: add code to log the sql exception log.Error( "error generating sequence", e ); throw; } finally { session.Batcher.CloseCommand( cmd, reader ); } }
public EntityDeleteAction(object id, object[] state, object version, object instance, IEntityPersister persister, bool isCascadeDeleteEnabled, ISessionImplementor session) : base(session, id, instance, persister) { this.state = state; this.version = version; this.isCascadeDeleteEnabled = isCascadeDeleteEnabled; }
public Nullifier(object self, bool isDelete, bool isEarlyInsert, ISessionImplementor session) { this.isDelete = isDelete; this.isEarlyInsert = isEarlyInsert; this.session = session; this.self = self; }
protected virtual object Load(ISessionImplementor session, object id, object optionalObject, object optionalId) { IList list = LoadEntity(session, id, uniqueKeyType, optionalObject, entityName, optionalId, persister); if (list.Count == 1) { return list[0]; } else if (list.Count == 0) { return null; } else { if (CollectionOwners != null) { return list[0]; } else { throw new HibernateException( string.Format("More than one row with the given identifier was found: {0}, for class: {1}", id, persister.EntityName)); } } }
public object Load(object id, object optionalObject, ISessionImplementor session) { if (log.IsDebugEnabled) { log.Debug(string.Format("loading entity: {0} using named query: {1}", persister.EntityName, queryName)); } AbstractQueryImpl query = (AbstractQueryImpl) session.GetNamedQuery(queryName); if (query.HasNamedParameters) { query.SetParameter(query.NamedParameters[0], id, persister.IdentifierType); } else { query.SetParameter(0, id, persister.IdentifierType); } query.SetOptionalId(id); query.SetOptionalEntityName(persister.EntityName); query.SetOptionalObject(optionalObject); query.SetFlushMode(FlushMode.Never); query.List(); // now look up the object we are really interested in! // (this lets us correctly handle proxies and multi-row // or multi-column queries) return session.PersistenceContext.GetEntity(session.GenerateEntityKey(id, persister)); }
/// <summary> /// Disassembles the object into a cacheable representation. /// </summary> /// <param name="value">The value to disassemble.</param> /// <param name="session">The <see cref="ISessionImplementor"/> is not used by this method.</param> /// <param name="owner">optional parent entity object (needed for collections) </param> /// <returns>The disassembled, deep cloned state of the object</returns> /// <remarks> /// This method calls DeepCopy if the value is not null. /// </remarks> public virtual object Disassemble(object value, ISessionImplementor session, object owner) { if (value == null) return null; return DeepCopy(value, session.EntityMode, session.Factory); }
/// <summary> /// Generates an identifer from the value of a Property. /// </summary> /// <param name="sessionImplementor">The <see cref="ISessionImplementor"/> this id is being generated in.</param> /// <param name="obj">The entity for which the id is being generated.</param> /// <returns> /// The identifier value from the associated object or /// <see cref="IdentifierGeneratorFactory.ShortCircuitIndicator"/> if the <c>session</c> /// already contains <c>obj</c>. /// </returns> public object Generate(ISessionImplementor sessionImplementor, object obj) { ISession session = (ISession)sessionImplementor; object associatedObject = sessionImplementor.Factory .GetClassMetadata(obj.GetType()) .GetPropertyValue(obj, propertyName, sessionImplementor.EntityMode); if (associatedObject == null) { throw new IdentifierGenerationException("attempted to assign id from null one-to-one property: " + propertyName); } EntityType type = (EntityType)sessionImplementor.Factory.GetClassMetadata(obj.GetType()).GetPropertyType(propertyName); object id; try { id = ForeignKeys.GetEntityIdentifierIfNotUnsaved(type.GetAssociatedEntityName(), associatedObject, sessionImplementor); } catch (TransientObjectException) { id = session.Save(associatedObject); } if (session.Contains(obj)) { //abort the save (the object is already saved by a circular cascade) return IdentifierGeneratorFactory.ShortCircuitIndicator; } return id; }
protected AbstractAuditWorkUnit(ISessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg, Object id) { this.sessionImplementor = sessionImplementor; this.verCfg = verCfg; this.EntityId = id; this.EntityName = entityName; }
private object[] GetValues(object entity, EntityEntry entry, EntityMode entityMode, bool mightBeDirty, ISessionImplementor session) { object[] loadedState = entry.LoadedState; Status status = entry.Status; IEntityPersister persister = entry.Persister; object[] values; if (status == Status.Deleted) { //grab its state saved at deletion values = entry.DeletedState; } else if (!mightBeDirty && loadedState != null) { values = loadedState; } else { CheckId(entity, persister, entry.Id, entityMode); // grab its current state values = persister.GetPropertyValues(entity, entityMode); CheckNaturalId(persister, entry, values, loadedState, entityMode, session); } return values; }
/// <summary> /// Creates a new PersistentSet initialized to the values in the Map. /// This constructor is NOT meant to be called from user code. /// </summary> /// <remarks> /// Only call this constructor if you consider the map initialized. /// </remarks> public PersistentSet(ISessionImplementor session, ISet collection) : base(session) { internalSet = collection; SetInitialized(); IsDirectlyAccessible = true; }
/// <summary> /// Create an action that will evict collection and entity regions based on queryspaces (table names). /// </summary> public BulkOperationCleanupAction(ISessionImplementor session, ISet<string> querySpaces) { //from H3.2 TODO: cache the autodetected information and pass it in instead. this.session = session; ISet<string> tmpSpaces = new HashedSet<string>(querySpaces); ISessionFactoryImplementor factory = session.Factory; IDictionary acmd = factory.GetAllClassMetadata(); foreach (DictionaryEntry entry in acmd) { string entityName = ((System.Type) entry.Key).FullName; IEntityPersister persister = factory.GetEntityPersister(entityName); string[] entitySpaces = persister.QuerySpaces; if (AffectedEntity(querySpaces, entitySpaces)) { if (persister.HasCache) { affectedEntityNames.Add(persister.EntityName); } ISet roles = session.Factory.GetCollectionRolesByEntityParticipant(persister.EntityName); if (roles != null) { affectedCollectionRoles.AddAll(roles); } for (int y = 0; y < entitySpaces.Length; y++) { tmpSpaces.Add(entitySpaces[y]); } } } spaces = new List<string>(tmpSpaces); }
/// <summary> /// Construct an initialized PersistentMap based off the values from the existing IDictionary. /// </summary> /// <param name="session">The ISession the PersistentMap should be a part of.</param> /// <param name="map">The IDictionary that contains the initial values.</param> public PersistentMap(ISessionImplementor session, IDictionary map) : base(session) { this.map = map; SetInitialized(); IsDirectlyAccessible = true; }
public override object ReplaceElements(object original, object target, object owner, IDictionary copyCache, ISessionImplementor session) { ICollectionPersister cp = session.Factory.GetCollectionPersister(Role); IDictionary result = (IDictionary)target; result.Clear(); IEnumerable iter = (IDictionary)original; foreach (DictionaryEntry me in iter) { object key = cp.IndexType.Replace(me.Key, null, session, owner, copyCache); object value = cp.ElementType.Replace(me.Value, null, session, owner, copyCache); result[key] = value; } var originalPc = original as IPersistentCollection; var resultPc = result as IPersistentCollection; if (originalPc != null && resultPc != null) { if (!originalPc.IsDirty) resultPc.ClearDirty(); } return result; }
public void EnlistInDistributedTransactionIfNeeded(ISessionImplementor session) { if (session.TransactionContext != null) return; if (System.Transactions.Transaction.Current == null) return; var transactionContext = new DistributedTransactionContext(session, System.Transactions.Transaction.Current); session.TransactionContext = transactionContext; logger.DebugFormat("enlisted into DTC transaction: {0}", transactionContext.AmbientTransation.IsolationLevel); session.AfterTransactionBegin(null); transactionContext.AmbientTransation.TransactionCompleted += delegate(object sender, TransactionEventArgs e) { bool wasSuccessful = false; try { wasSuccessful = e.Transaction.TransactionInformation.Status == TransactionStatus.Committed; } catch (ObjectDisposedException ode) { logger.Warn("Completed transaction was disposed, assuming transaction rollback", ode); } session.AfterTransactionCompletion(wasSuccessful, null); if (transactionContext.ShouldCloseSessionOnDistributedTransactionCompleted) { session.CloseSessionFromDistributedTransaction(); } session.TransactionContext = null; }; transactionContext.AmbientTransation.EnlistVolatile(transactionContext, EnlistmentOptions.EnlistDuringPrepareRequired); }
protected override object GetResultColumnOrRow(object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) { object[] result; string[] aliases; if (translator.HasProjection) { IType[] types = translator.ProjectedTypes; result = new object[types.Length]; string[] columnAliases = translator.ProjectedColumnAliases; for (int i = 0; i < result.Length; i++) { result[i] = types[i].NullSafeGet(rs, columnAliases[i], session, null); } aliases = translator.ProjectedAliases; } else { result = row; aliases = userAliases; } return translator.RootCriteria.ResultTransformer.TransformTuple(result, aliases); }
/// <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> /// Bind named parameters to the <tt>PreparedStatement</tt>. This has an /// empty implementation on this superclass and should be implemented by /// subclasses (queries) which allow named parameters. /// </summary> private void BindNamedParameters(IDbCommand ps, IDictionary namedParams, int start, ISessionImplementor session) { if (namedParams != null) { // assumes that types are all of span 1 int result = 0; foreach (DictionaryEntry param in namedParams) { string name = (string)param.Key; TypedValue typedval = (TypedValue)param.Value; int[] locs = GetNamedParameterLocs(name); for (int i = 0; i < locs.Length; i++) { if (log.IsDebugEnabled) { log.Debug(string.Format("BindNamedParameters() {0} -> {1} [{2}]", typedval.Value, name, (locs[i] + start))); } typedval.Type.NullSafeSet(ps, typedval.Value, locs[i] + start, session); } result += locs.Length; } return; } else { return; } }
private bool FlushMightBeNeeded(ISessionImplementor source) { return !(source.FlushMode < FlushMode.Auto) && source.DontFlushFromFind == 0 && ((source.PersistenceContext.EntityEntries.Count > 0) || (source.PersistenceContext.CollectionEntries.Count > 0)); }
/// <summary> /// Initialize the role of the collection. /// </summary> /// <param name="collection">The collection to be updated by reachibility. </param> /// <param name="type">The type of the collection. </param> /// <param name="entity">The owner of the collection. </param> /// <param name="session">The session.</param> public static void ProcessReachableCollection(IPersistentCollection collection, CollectionType type, object entity, ISessionImplementor session) { collection.Owner = entity; CollectionEntry ce = session.PersistenceContext.GetCollectionEntry(collection); if (ce == null) { // refer to comment in StatefulPersistenceContext.addCollection() throw new HibernateException(string.Format("Found two representations of same collection: {0}", type.Role)); } // The CollectionEntry.isReached() stuff is just to detect any silly users // who set up circular or shared references between/to collections. if (ce.IsReached) { // We've been here before throw new HibernateException(string.Format("Found shared references to a collection: {0}", type.Role)); } ce.IsReached = true; ISessionFactoryImplementor factory = session.Factory; ICollectionPersister persister = factory.GetCollectionPersister(type.Role); ce.CurrentPersister = persister; ce.CurrentKey = type.GetKeyOfOwner(entity, session); //TODO: better to pass the id in as an argument? if (log.IsDebugEnabled) { log.Debug("Collection found: " + MessageHelper.InfoString(persister, ce.CurrentKey, factory) + ", was: " + MessageHelper.InfoString(ce.LoadedPersister, ce.LoadedKey, factory) + (collection.WasInitialized ? " (initialized)" : " (uninitialized)")); } PrepareCollectionForUpdate(collection, ce); }
/// <summary> /// Initializes a new instance of <see cref="ScheduledCollectionUpdate"/>. /// </summary> /// <param name="collection">The <see cref="IPersistentCollection"/> to update.</param> /// <param name="persister">The <see cref="ICollectionPersister"/> that is responsible for the persisting the Collection.</param> /// <param name="id">The identifier of the Collection owner.</param> /// <param name="emptySnapshot">Indicates if the Collection was empty when it was loaded.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> public ScheduledCollectionUpdate(IPersistentCollection collection, ICollectionPersister persister, object id, bool emptySnapshot, ISessionImplementor session) : base(persister, id, session) { _collection = collection; _emptySnapshot = emptySnapshot; }
public INHibernateProxy GetProxy(object id, ISessionImplementor session) { INHibernateProxy proxy; try { object generatedProxy; LazyInitializer initializer = new LazyInitializer(_entityName, _persistentClass, id, _getIdentifierMethod, _setIdentifierMethod, _componentIdType, session); IInterceptor[] interceptors = new IInterceptor[] { initializer }; object[] args; if (_isClassProxy) { args = new object[] { interceptors }; } else { args = new object[] { interceptors, new object() }; } generatedProxy = Activator.CreateInstance(_proxyType, args); initializer._constructed = true; proxy = (INHibernateProxy)generatedProxy; } catch (Exception e) { string message = "Creating a proxy instance failed"; _log.Error(message, e); throw new HibernateException(message, e); } return proxy; }
public INHibernateProxy GetProxy(object id, ISessionImplementor session) { return new MapProxy(new MapLazyInitializer(entityName, id, session)); }
/// <summary> /// Perform the second step of 2-phase load. Fully initialize the entity instance. /// After processing a JDBC result set, we "resolve" all the associations /// between the entities which were instantiated and had their state /// "hydrated" into an array /// </summary> internal static async Task InitializeEntityAsync(object entity, bool readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent, Action <IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!) Stopwatch stopWatch = null; if (session.Factory.Statistics.IsStatisticsEnabled) { stopWatch = Stopwatch.StartNew(); } IPersistenceContext persistenceContext = session.PersistenceContext; EntityEntry entityEntry = persistenceContext.GetEntry(entity); if (entityEntry == null) { throw new AssertionFailure("possible non-threadsafe access to the session"); } IEntityPersister persister = entityEntry.Persister; object id = entityEntry.Id; object[] hydratedState = entityEntry.LoadedState; if (log.IsDebugEnabled()) { log.Debug("resolving associations for {0}", MessageHelper.InfoString(persister, id, session.Factory)); } IType[] types = persister.PropertyTypes; var collectionToResolveIndexes = new List <int>(hydratedState.Length); for (int i = 0; i < hydratedState.Length; i++) { object value = hydratedState[i]; if (!Equals(LazyPropertyInitializer.UnfetchedProperty, value) && !(Equals(BackrefPropertyAccessor.Unknown, value))) { if (types[i].IsCollectionType) { // Resolve them last, because they may depend on other properties if they use a property-ref collectionToResolveIndexes.Add(i); continue; } hydratedState[i] = await(types[i].ResolveIdentifierAsync(value, session, entity, cancellationToken)).ConfigureAwait(false); } } foreach (var i in collectionToResolveIndexes) { hydratedState[i] = await(types[i].ResolveIdentifierAsync(hydratedState[i], session, entity, cancellationToken)).ConfigureAwait(false); } //Must occur after resolving identifiers! if (session.IsEventSource) { preLoadEvent.Entity = entity; preLoadEvent.State = hydratedState; preLoadEvent.Id = id; preLoadEvent.Persister = persister; IPreLoadEventListener[] listeners = session.Listeners.PreLoadEventListeners; for (int i = 0; i < listeners.Length; i++) { await(listeners[i].OnPreLoadAsync(preLoadEvent, cancellationToken)).ConfigureAwait(false); } } persister.SetPropertyValues(entity, hydratedState); ISessionFactoryImplementor factory = session.Factory; if (persister.HasCache && session.CacheMode.HasFlag(CacheMode.Put)) { if (log.IsDebugEnabled()) { log.Debug("adding entity to second-level cache: {0}", MessageHelper.InfoString(persister, id, session.Factory)); } object version = Versioning.GetVersion(hydratedState, persister); CacheEntry entry = await(CacheEntry.CreateAsync(hydratedState, persister, version, session, entity, cancellationToken)).ConfigureAwait(false); CacheKey cacheKey = session.GenerateCacheKey(id, persister.IdentifierType, persister.RootEntityName); if (cacheBatchingHandler != null && persister.IsBatchLoadable) { cacheBatchingHandler( persister, new CachePutData( cacheKey, persister.CacheEntryStructure.Structure(entry), version, persister.IsVersioned ? persister.VersionType.Comparator : null, UseMinimalPuts(session, entityEntry))); } else { bool put = await(persister.Cache.PutAsync(cacheKey, persister.CacheEntryStructure.Structure(entry), session.Timestamp, version, persister.IsVersioned ? persister.VersionType.Comparator : null, UseMinimalPuts(session, entityEntry), cancellationToken)).ConfigureAwait(false); if (put && factory.Statistics.IsStatisticsEnabled) { factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName); } } } bool isReallyReadOnly = readOnly; if (!persister.IsMutable) { isReallyReadOnly = true; } else { object proxy = persistenceContext.GetProxy(entityEntry.EntityKey); if (proxy != null) { // there is already a proxy for this impl // only set the status to read-only if the proxy is read-only isReallyReadOnly = ((INHibernateProxy)proxy).HibernateLazyInitializer.ReadOnly; } } if (isReallyReadOnly) { //no need to take a snapshot - this is a //performance optimization, but not really //important, except for entities with huge //mutable property values persistenceContext.SetEntryStatus(entityEntry, Status.ReadOnly); } else { //take a snapshot TypeHelper.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session); persistenceContext.SetEntryStatus(entityEntry, Status.Loaded); } persister.AfterInitialize(entity, session); if (session.IsEventSource) { postLoadEvent.Entity = entity; postLoadEvent.Id = id; postLoadEvent.Persister = persister; IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners; for (int i = 0; i < listeners.Length; i++) { listeners[i].OnPostLoad(postLoadEvent); } } if (log.IsDebugEnabled()) { log.Debug("done materializing entity {0}", MessageHelper.InfoString(persister, id, session.Factory)); } if (stopWatch != null) { stopWatch.Stop(); factory.StatisticsImplementor.LoadEntity(persister.EntityName, stopWatch.Elapsed); } }
public IPersistentCollection Wrap(ISessionImplementor session, object collection) { return(new PersistentMySet <T>(session, (IMySet <T>)collection)); }
public object ReplaceElements(object original, object target, NHibernate.Persister.Collection.ICollectionPersister persister, object owner, IDictionary copyCache, ISessionImplementor session) { var result = (MySet <T>)target; result.Clear(); foreach (var item in (IEnumerable <T>)original) { result.Add(item); } return(result); }
public IPersistentCollection Instantiate(ISessionImplementor session, NHibernate.Persister.Collection.ICollectionPersister persister) { return(new PersistentMySet <T>(session)); }
public override async Task <object> DoWorkInCurrentTransactionAsync(ISessionImplementor session, DbConnection conn, DbTransaction transaction, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); long result; int updatedRows; do { try { object selectedValue; var selectCmd = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, _selectQuery, SqlTypeFactory.NoTypes); using (selectCmd) { selectCmd.Connection = conn; selectCmd.Transaction = transaction; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand(selectCmd, FormatStyle.Basic); selectedValue = await(selectCmd.ExecuteScalarAsync(cancellationToken)).ConfigureAwait(false); } if (selectedValue == null) { Log.Error("could not read a hi value - you need to populate the table: {0}", _tableName); throw new IdentifierGenerationException("could not read a hi value - you need to populate the table: " + _tableName); } result = Convert.ToInt64(selectedValue); } catch (OperationCanceledException) { throw; } catch (Exception sqle) { Log.Error(sqle, "could not read a hi value"); throw; } try { var updateCmd = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, _updateQuery, _updateParameterTypes); using (updateCmd) { updateCmd.Connection = conn; updateCmd.Transaction = transaction; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand(updateCmd, FormatStyle.Basic); int increment = _applyIncrementSizeToSourceValues ? _incrementSize : 1; updateCmd.Parameters[0].Value = result + increment; updateCmd.Parameters[1].Value = result; updatedRows = await(updateCmd.ExecuteNonQueryAsync(cancellationToken)).ConfigureAwait(false); } } catch (OperationCanceledException) { throw; } catch (Exception sqle) { Log.Error(sqle, "could not update hi value in: {0}", _tableName); throw; } }while (updatedRows == 0); _accessCounter++; return(result); }
public override async Task <object> DoWorkInCurrentTransactionAsync(ISessionImplementor session, DbConnection conn, DbTransaction transaction, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); long result; int rows; do { //the loop ensure atomicitiy of the //select + uspdate even for no transaction //or read committed isolation level (needed for .net?) var qps = conn.CreateCommand(); DbDataReader rs = null; qps.CommandText = query; qps.CommandType = CommandType.Text; qps.Transaction = transaction; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand("Reading high value:", qps, FormatStyle.Basic); try { rs = await(qps.ExecuteReaderAsync(cancellationToken)).ConfigureAwait(false); if (!await(rs.ReadAsync(cancellationToken)).ConfigureAwait(false)) { string err; if (string.IsNullOrEmpty(whereClause)) { err = "could not read a hi value - you need to populate the table: " + tableName; } else { err = string.Format("could not read a hi value from table '{0}' using the where clause ({1})- you need to populate the table.", tableName, whereClause); } log.Error(err); throw new IdentifierGenerationException(err); } result = Convert.ToInt64(columnType.Get(rs, 0, session)); } catch (Exception e) { log.Error("could not read a hi value", e); throw; } finally { if (rs != null) { rs.Close(); } qps.Dispose(); } var ups = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, updateSql, parameterTypes); ups.Connection = conn; ups.Transaction = transaction; try { columnType.Set(ups, result + 1, 0, session); columnType.Set(ups, result, 1, session); PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand("Updating high value:", ups, FormatStyle.Basic); rows = await(ups.ExecuteNonQueryAsync(cancellationToken)).ConfigureAwait(false); } catch (Exception e) { log.Error("could not update hi value in: " + tableName, e); throw; } finally { ups.Dispose(); } }while (rows == 0); return(result); }
/// <summary> /// When implemented by a class, gets the object in the /// <see cref="DbDataReader"/> for the Property. /// </summary> /// <param name="rs">The <see cref="DbDataReader"/> that contains the value.</param> /// <param name="name">The name of the field to get the value from.</param> /// <param name="session">The session for which the operation is done.</param> /// <returns>An object with the value from the database.</returns> /// <remarks> /// Most implementors just call the <see cref="Get(DbDataReader, int, ISessionImplementor)"/> /// overload of this method. /// </remarks> public abstract object Get(DbDataReader rs, string name, ISessionImplementor session);
/// <summary> /// When implemented by a class, put the value from the mapped /// Property into to the <see cref="DbCommand"/>. /// </summary> /// <param name="cmd">The <see cref="DbCommand"/> to put the value into.</param> /// <param name="value">The object that contains the value.</param> /// <param name="index">The index of the <see cref="DbParameter"/> to start writing the values to.</param> /// <param name="session">The session for which the operation is done.</param> /// <remarks> /// Implementors do not need to handle possibility of null values because this will /// only be called from <see cref="NullSafeSet(DbCommand, object, int, ISessionImplementor)"/> after /// it has checked for nulls. /// </remarks> public abstract void Set(DbCommand cmd, object value, int index, ISessionImplementor session);
public void SetSession(ISessionImplementor s) { }
/// <inheritdoc /> /// <remarks> /// <para> /// This implementation forwards the call to <see cref="NullSafeGet(DbDataReader, String, ISessionImplementor)" />. /// </para> /// <para> /// It has been "sealed" because the Types inheriting from <see cref="NullableType"/> /// do not need to and should not override this method. All of their implementation /// should be in <see cref="NullSafeGet(DbDataReader, String, ISessionImplementor)" />. /// </para> /// </remarks> public sealed override object NullSafeGet(DbDataReader rs, string name, ISessionImplementor session, object owner) { return(NullSafeGet(rs, name, session)); }
/// <summary> /// When implemented by a class, gets the object in the /// <see cref="DbDataReader"/> for the Property. /// </summary> /// <param name="rs">The <see cref="DbDataReader"/> that contains the value.</param> /// <param name="index">The index of the field to get the value from.</param> /// <param name="session">The session for which the operation is done.</param> /// <returns>An object with the value from the database.</returns> public abstract object Get(DbDataReader rs, int index, ISessionImplementor session);
/// <inheritdoc /> /// <remarks> /// <para> /// This method has been "sealed" because the Types inheriting from <see cref="NullableType"/> /// do not need to and should not override this method. /// </para> /// <para> /// This method checks to see if value is null, if it is then the value of /// <see cref="DBNull"/> is written to the <see cref="DbCommand"/>. /// </para> /// <para> /// If the value is not null, then the method <see cref="Set(DbCommand, object, int, ISessionImplementor)"/> /// is called and that method is responsible for setting the value. /// </para> /// </remarks> public sealed override void NullSafeSet(DbCommand st, object value, int index, ISessionImplementor session) { if (value == null) { if (IsDebugEnabled) { Log.Debug("binding null to parameter: {0}", index); } //Do we check IsNullable? // TODO: find out why a certain Parameter would not take a null value... // From reading the .NET SDK the default is to NOT accept a null value. // I definitely need to look into this more... st.Parameters[index].Value = DBNull.Value; } else { if (IsDebugEnabled) { Log.Debug("binding '{0}' to parameter: {1}", ToString(value), index); } Set(st, value, index, session); } }
public override bool IsDirty(object old, object current, bool[] checkable, ISessionImplementor session) { return(checkable[0] && IsDirty(old, current, session)); }
public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) { return(Get(owner)); }
/// <summary> /// Extracts the values of the fields from the DataReader /// </summary> /// <param name="rs">The DataReader positioned on the correct record</param> /// <param name="names">An array of field names.</param> /// <param name="session">The session for which the operation is done.</param> /// <returns>The value off the field from the DataReader</returns> /// <remarks> /// In this class this just ends up passing the first name to the NullSafeGet method /// that takes a string, not a string[]. /// /// I don't know why this method is in here - it doesn't look like anybody that inherits /// from NullableType overrides this... /// /// TODO: determine if this is needed /// </remarks> public virtual object NullSafeGet(DbDataReader rs, string[] names, ISessionImplementor session) { return(NullSafeGet(rs, names[0], session)); }
public override object Get(object value, ISessionImplementor session, object owner) { return(((T[])value).ToList()); }
public override void NullSafeSet(DbCommand st, object value, int index, bool[] settable, ISessionImplementor session) { if (settable[0]) { NullSafeSet(st, value, index, session); } }
/// <summary> /// Load an instance by a unique key that is not the primary key. /// </summary> /// <param name="entityName">The name of the entity to load </param> /// <param name="uniqueKeyPropertyName">The name of the property defining the unique key. </param> /// <param name="key">The unique key property value. </param> /// <param name="session">The originating session. </param> /// <returns> The loaded entity </returns> public object LoadByUniqueKey(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session) { ISessionFactoryImplementor factory = session.Factory; IUniqueKeyLoadable persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName); //TODO: implement caching?! proxies?! var keyType = GetIdentifierOrUniqueKeyType(factory) // EntityUniqueKey was doing this on the type. I suspect this was needed only for its usage in Loader, // which can work with entities as keys not yet instanciated and just represented by their identifiers. // But since removing this call from EntityUniqueKey is done for a patch and that the code path here has // no known bugs with this GetSemiResolvedType, moving its call here for avoiding altering this code // path. See GH1645. .GetSemiResolvedType(factory); EntityUniqueKey euk = new EntityUniqueKey( entityName, uniqueKeyPropertyName, key, keyType, session.Factory); IPersistenceContext persistenceContext = session.PersistenceContext; try { object result = persistenceContext.GetEntity(euk); if (result == null) { result = persister.LoadByUniqueKey(uniqueKeyPropertyName, key, session); } return(result == null ? null : persistenceContext.ProxyFor(result)); } catch (HibernateException) { // Do not call Convert on HibernateExceptions throw; } catch (Exception sqle) { throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey"); } }
public override void Set(DbParameter parameter, object value, ISessionImplementor session) { parameter.Value = value; }
public abstract override object Hydrate(DbDataReader rs, string[] names, ISessionImplementor session, object owner);
public virtual bool IsNull(object owner, ISessionImplementor session) { return(false); }
protected internal object GetIdentifier(object value, ISessionImplementor session) { return(ForeignKeys.GetEntityIdentifierIfNotUnsaved(GetAssociatedEntityName(), value, session)); //tolerates nulls }
/// <summary> Convenience method to locate the identifier type of the associated entity. </summary> /// <param name="session">The originating session </param> /// <returns> The identifier type </returns> internal virtual IType GetIdentifierType(ISessionImplementor session) { return(GetIdentifierType(session.Factory)); }
public bool Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, bool isNaturalKeyLookup, ISessionImplementor session) { if (isNaturalKeyLookup && result.Count == 0) return false; var ts = session.Factory.Settings.CacheProvider.NextTimestamp(); Log.Debug("caching query results in region: '{0}'; {1}", _regionName, key); Cache.Put(key, GetCacheableResult(returnTypes, session, result, ts)); return true; }
/// <summary> /// Converts the id contained in the <see cref="DbDataReader"/> to an object. /// </summary> /// <param name="rs">The <see cref="DbDataReader"/> that contains the query results.</param> /// <param name="names">A string array of column names that contain the id.</param> /// <param name="session">The <see cref="ISessionImplementor"/> this is occurring in.</param> /// <param name="owner">The object that this Entity will be a part of.</param> /// <returns> /// An instance of the object or <see langword="null" /> if the identifer was null. /// </returns> public override sealed object NullSafeGet(DbDataReader rs, string[] names, ISessionImplementor session, object owner) { return(ResolveIdentifier(Hydrate(rs, names, session, owner), session, owner)); }
public IList Get(QueryKey key, ICacheAssembler[] returnTypes, bool isNaturalKeyLookup, ISet<string> spaces, ISessionImplementor session) { if (Log.IsDebugEnabled()) Log.Debug("checking cached query results in region: '{0}'; {1}", _regionName, key); var cacheable = (IList) Cache.Get(key); if (cacheable == null) { Log.Debug("query results were not found in cache: {0}", key); return null; } var timestamp = (long) cacheable[0]; if (Log.IsDebugEnabled()) Log.Debug("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(spaces)); if (!isNaturalKeyLookup && !IsUpToDate(spaces, timestamp)) { Log.Debug("cached query results were not up to date for: {0}", key); return null; } return GetResultFromCacheable(key, returnTypes, isNaturalKeyLookup, session, cacheable); }
public override object NullSafeGet(DbDataReader rs, string name, ISessionImplementor session, object owner) { return(NullSafeGet(rs, new string[] { name }, session, owner)); }
public override object DoWorkInCurrentTransaction(ISessionImplementor session, DbConnection conn, DbTransaction transaction) { long result; int updatedRows; do { object selectedValue; try { var selectCmd = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, selectQuery, selectParameterTypes); using (selectCmd) { selectCmd.Connection = conn; selectCmd.Transaction = transaction; string s = selectCmd.CommandText; selectCmd.Parameters[0].Value = SegmentValue; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand(selectCmd, FormatStyle.Basic); selectedValue = selectCmd.ExecuteScalar(); } if (selectedValue == null) { result = InitialValue; var insertCmd = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, insertQuery, insertParameterTypes); using (insertCmd) { insertCmd.Connection = conn; insertCmd.Transaction = transaction; insertCmd.Parameters[0].Value = SegmentValue; insertCmd.Parameters[1].Value = result; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand(insertCmd, FormatStyle.Basic); insertCmd.ExecuteNonQuery(); } } else { result = Convert.ToInt64(selectedValue); } } catch (Exception ex) { log.Error("Unable to read or initialize hi value in " + TableName, ex); throw; } try { var updateCmd = session.Factory.ConnectionProvider.Driver.GenerateCommand(CommandType.Text, updateQuery, updateParameterTypes); using (updateCmd) { updateCmd.Connection = conn; updateCmd.Transaction = transaction; int increment = Optimizer.ApplyIncrementSizeToSourceValues ? IncrementSize : 1; updateCmd.Parameters[0].Value = result + increment; updateCmd.Parameters[1].Value = result; updateCmd.Parameters[2].Value = SegmentValue; PersistentIdGeneratorParmsNames.SqlStatementLogger.LogCommand(updateCmd, FormatStyle.Basic); updatedRows = updateCmd.ExecuteNonQuery(); } } catch (Exception ex) { log.Error("Unable to update hi value in " + TableName, ex); throw; } } while (updatedRows == 0); TableAccessCount++; return result; }
/// <inheritdoc /> public IList[] GetMany( QueryKey[] keys, QueryParameters[] queryParameters, ICacheAssembler[][] returnTypes, ISet<string>[] spaces, ISessionImplementor session) { if (Log.IsDebugEnabled()) Log.Debug("checking cached query results in region: '{0}'; {1}", _regionName, StringHelper.CollectionToString(keys)); var cacheables = _cache.GetMany(keys); var spacesToCheck = new List<ISet<string>>(); var checkedSpacesIndexes = new HashSet<int>(); var checkedSpacesTimestamp = new List<long>(); for (var i = 0; i < keys.Length; i++) { var cacheable = (IList) cacheables[i]; if (cacheable == null) { Log.Debug("query results were not found in cache: {0}", keys[i]); continue; } var querySpaces = spaces[i]; if (queryParameters[i].NaturalKeyLookup || querySpaces.Count == 0) continue; spacesToCheck.Add(querySpaces); checkedSpacesIndexes.Add(i); // The timestamp is the first element of the cache result. checkedSpacesTimestamp.Add((long) cacheable[0]); if (Log.IsDebugEnabled()) Log.Debug("Checking query spaces for up-to-dateness [{0}]", StringHelper.CollectionToString(querySpaces)); } var upToDates = spacesToCheck.Count > 0 ? _updateTimestampsCache.AreUpToDate(spacesToCheck.ToArray(), checkedSpacesTimestamp.ToArray()) : Array.Empty<bool>(); var upToDatesIndex = 0; var persistenceContext = session.PersistenceContext; var defaultReadOnlyOrig = persistenceContext.DefaultReadOnly; var results = new IList[keys.Length]; var finalReturnTypes = new ICacheAssembler[keys.Length][]; try { session.PersistenceContext.BatchFetchQueue.InitializeQueryCacheQueue(); for (var i = 0; i < keys.Length; i++) { var cacheable = (IList) cacheables[i]; if (cacheable == null) continue; var key = keys[i]; if (checkedSpacesIndexes.Contains(i) && !upToDates[upToDatesIndex++]) { Log.Debug("cached query results were not up to date for: {0}", key); continue; } var queryParams = queryParameters[i]; if (queryParams.IsReadOnlyInitialized) persistenceContext.DefaultReadOnly = queryParams.ReadOnly; else queryParams.ReadOnly = persistenceContext.DefaultReadOnly; Log.Debug("returning cached query results for: {0}", key); finalReturnTypes[i] = GetReturnTypes(key, returnTypes[i], cacheable); PerformBeforeAssemble(finalReturnTypes[i], session, cacheable); } for (var i = 0; i < keys.Length; i++) { if (finalReturnTypes[i] == null) { continue; } var queryParams = queryParameters[i]; // Adjust the session cache mode, as PerformAssemble assemble types which may cause // entity loads, which may interact with the cache. using (session.SwitchCacheMode(queryParams.CacheMode)) { try { results[i] = PerformAssemble(keys[i], finalReturnTypes[i], queryParams.NaturalKeyLookup, session, (IList) cacheables[i]); } finally { persistenceContext.DefaultReadOnly = defaultReadOnlyOrig; } } } for (var i = 0; i < keys.Length; i++) { if (finalReturnTypes[i] == null) { continue; } var queryParams = queryParameters[i]; // Adjust the session cache mode, as InitializeCollections will initialize collections, // which may interact with the cache. using (session.SwitchCacheMode(queryParams.CacheMode)) { try { InitializeCollections(finalReturnTypes[i], session, results[i], (IList) cacheables[i]); } finally { persistenceContext.DefaultReadOnly = defaultReadOnlyOrig; } } } } finally { session.PersistenceContext.BatchFetchQueue.TerminateQueryCacheQueue(); } return results; }