Beispiel #1
0
        /// <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?!

            EntityUniqueKey euk =
                new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, GetIdentifierOrUniqueKeyType(factory),
                                    session.EntityMode, 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");
            }
        }
Beispiel #2
0
        public async Task AlteredBankShouldBeJoinFetchedAsync()
        {
            using (var s1 = OpenSession())
            {
                using (var tx = s1.BeginTransaction())
                {
                    // Put them all in s1 cache.
                    await(s1.CreateQuery("from Bank").ListAsync());
                    await(tx.CommitAsync());
                }

                string       oldCode;
                const string newCode = "12345";
                // Alter the bank code with another session.
                using (var s2 = OpenSession())
                    using (var tx2 = s2.BeginTransaction())
                    {
                        var accounts = await(s2.Query <Account>().ToListAsync());
                        foreach (var account in accounts)
                        {
                            account.Bank = null;
                        }
                        await(s2.FlushAsync());
                        var bank = await(s2.Query <Bank>().SingleAsync());
                        oldCode   = bank.Code;
                        bank.Code = newCode;
                        await(s2.FlushAsync());
                        foreach (var account in accounts)
                        {
                            account.Bank = bank;
                        }
                        await(tx2.CommitAsync());
                    }

                // Check querying them with s1 is still consistent
                using (var tx = s1.BeginTransaction())
                {
                    var accounts        = await(s1.CreateQuery("from Account a left join fetch a.Bank").ListAsync <Account>());
                    var associatedBanks = accounts.Select(x => x.Bank).ToList();
                    Assert.That(associatedBanks, Has.All.Not.Null,
                                "One bank or more failed loading.");
                    Assert.That(associatedBanks, Has.All.Matches <object>(NHibernateUtil.IsInitialized),
                                "One bank or more was lazily loaded.");
                    Assert.That(associatedBanks, Has.All.Property(nameof(Bank.Code)).EqualTo(oldCode),
                                "One bank or more has no more the old code.");

                    await(tx.CommitAsync());
                    // Do not check statements count: we are in a special case defeating the eager fetching, because
                    // we have stale data in session for the bank code.
                    // But check that the new code, supposed to be unknown for the session, is not cached.
                    var persister = Sfi.GetEntityPersister(typeof(Bank).FullName);
                    var index     = ((IUniqueKeyLoadable)persister).GetPropertyIndex(nameof(Bank.Code));
                    var type      = persister.PropertyTypes[index];
                    var euk       = new EntityUniqueKey(persister.EntityName, nameof(Bank.Code), newCode, type, Sfi);
                    Assert.That(s1.GetSessionImplementation().PersistenceContext.GetEntity(euk),
                                Is.Null, "Found a bank associated to the new code in s1");
                }
            }
        }
        public void Add(ISitecoreDomainEntity entity)
        {
            var key = new EntityUniqueKey(entity.Id, entity.GetType());

            if (!m_innerCache.ContainsKey(key))
            {
                m_innerCache.Add(key, entity);
            }
        }
Beispiel #4
0
        /// <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>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> The loaded entity </returns>
        public async Task <object> LoadByUniqueKeyAsync(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            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 = await(persister.LoadByUniqueKeyAsync(uniqueKeyPropertyName, key, session, cancellationToken)).ConfigureAwait(false);
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }
Beispiel #5
0
        /// <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>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns> The loaded entity </returns>
        public async Task <object> LoadByUniqueKeyAsync(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ISessionFactoryImplementor factory   = session.Factory;
            IUniqueKeyLoadable         persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

            //TODO: implement caching?! proxies?!

            var keyType = GetIdentifierOrUniqueKeyType(factory)
                          .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 = await(persister.LoadByUniqueKeyAsync(uniqueKeyPropertyName, key, session, cancellationToken)).ConfigureAwait(false);
                    if (result == null && !IsNullable)
                    {
                        factory.EntityNotFoundDelegate.HandleEntityNotFound(entityName, uniqueKeyPropertyName, key);
                    }
                }
                return(result == null ? null : persistenceContext.ProxyFor(result));
            }
            catch (OperationCanceledException) { throw; }
            catch (HibernateException)
            {
                // Do not call Convert on HibernateExceptions
                throw;
            }
            catch (Exception sqle)
            {
                throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
            }
        }