예제 #1
0
        protected internal virtual void putInternal(CachedDbEntity entityToAdd)
        {
            Type type     = entityToAdd.Entity.GetType();
            Type cacheKey = cacheKeyMapping.getEntityCacheKey(type);

            IDictionary <string, CachedDbEntity> map = cachedEntites[cacheKey];

            if (map == null)
            {
                map = new Dictionary <string, CachedDbEntity>();
                cachedEntites[cacheKey] = map;
            }

            // check whether this object is already present in the cache
            CachedDbEntity existingCachedEntity = map[entityToAdd.Entity.Id];

            if (existingCachedEntity == null)
            {
                // no such entity exists -> put it into the cache
                map[entityToAdd.Entity.Id] = entityToAdd;
            }
            else
            {
                // the same entity is already cached
                switch (entityToAdd.EntityState)
                {
                case TRANSIENT:
                    // cannot put TRANSIENT entity if entity with same id already exists in cache.
                    if (existingCachedEntity.EntityState == TRANSIENT)
                    {
                        throw LOG.entityCacheDuplicateEntryException("TRANSIENT", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState);
                    }
                    else
                    {
                        throw LOG.alreadyMarkedEntityInEntityCacheException(entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState);
                    }

                case PERSISTENT:
                    if (existingCachedEntity.EntityState == PERSISTENT)
                    {
                        // use new entity state, replacing the existing one.
                        map[entityToAdd.Entity.Id] = entityToAdd;
                        break;
                    }
                    if (existingCachedEntity.EntityState == DELETED_PERSISTENT || existingCachedEntity.EntityState == DELETED_MERGED)
                    {
                        // ignore put -> this is already marked to be deleted
                        break;
                    }

                    // otherwise fail:
                    throw LOG.entityCacheDuplicateEntryException("PERSISTENT", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState);

                case MERGED:
                    if (existingCachedEntity.EntityState == PERSISTENT || existingCachedEntity.EntityState == MERGED)
                    {
                        // use new entity state, replacing the existing one.
                        map[entityToAdd.Entity.Id] = entityToAdd;
                        break;
                    }
                    if (existingCachedEntity.EntityState == DELETED_PERSISTENT || existingCachedEntity.EntityState == DELETED_MERGED)
                    {
                        // ignore put -> this is already marked to be deleted
                        break;
                    }

                    // otherwise fail:
                    throw LOG.entityCacheDuplicateEntryException("MERGED", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState);

                default:
                    // deletes are always added
                    map[entityToAdd.Entity.Id] = entityToAdd;
                    break;
                }
            }
        }