コード例 #1
0
        private String GetMappedBy(Mapping.Collection collectionValue)
        {
            PersistentClass referencedClass = ((OneToMany)collectionValue.Element).AssociatedClass;

            // If there's an @AuditMappedBy specified, returning it directly.
            String auditMappedBy = propertyAuditingData.AuditMappedBy;

            if (auditMappedBy != null)
            {
                return(auditMappedBy);
            }

            IEnumerator <Property> assocClassProps = referencedClass.PropertyIterator.GetEnumerator();

            while (assocClassProps.MoveNext())
            {
                Property property = assocClassProps.Current;

                if (Toolz.IteratorsContentEqual(property.Value.ColumnIterator.GetEnumerator(),
                                                collectionValue.Key.ColumnIterator.GetEnumerator()))
                {
                    return(property.Name);
                }
            }

            throw new MappingException("Unable to read the mapped by attribute for " + propertyName + " in "
                                       + referencingEntityName + "!");
        }
コード例 #2
0
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="metaDataStore"></param>
        /// <param name="mainGenerator">Main generator, giving access to configuration and the basic mapper.</param>
        /// <param name="propertyValue">Value of the collection, as mapped by Hibernate.</param>
        /// <param name="currentMapper">Mapper, to which the appropriate {@link org.hibernate.envers.entities.mapper.PropertyMapper} will be added.</param>
        /// <param name="referencingEntityName">Name of the entity that owns this collection.</param>
        /// <param name="xmlMappingData">In case this collection requires a middle table, additional mapping documents will be created using this object.</param>
        /// <param name="propertyAuditingData">
        /// Property auditing (meta-)data. Among other things, holds the name of the
        /// property that references the collection in the referencing entity, the user data for middle (join)
        /// table and the value of the <code>@MapKey</code> annotation, if there was one.
        /// </param>
        public CollectionMetadataGenerator(IMetaDataStore metaDataStore,
                                           AuditMetadataGenerator mainGenerator,
                                           Mapping.Collection propertyValue,
                                           ICompositeMapperBuilder currentMapper,
                                           string referencingEntityName,
                                           EntityXmlMappingData xmlMappingData,
                                           PropertyAuditingData propertyAuditingData)
        {
            _metaDataStore         = metaDataStore;
            _mainGenerator         = mainGenerator;
            _propertyValue         = propertyValue;
            _currentMapper         = currentMapper;
            _referencingEntityName = referencingEntityName;
            _xmlMappingData        = xmlMappingData;
            _propertyAuditingData  = propertyAuditingData;

            _propertyName = propertyAuditingData.Name;

            _referencingEntityConfiguration = mainGenerator.EntitiesConfigurations[referencingEntityName];
            if (_referencingEntityConfiguration == null)
            {
                throw new MappingException("Unable to read auditing configuration for " + referencingEntityName + "!");
            }

            _referencedEntityName = MappingTools.ReferencedEntityName(propertyValue.Element);
        }
コード例 #3
0
 public OneToManyPersister(Mapping.Collection collection, ICacheConcurrencyStrategy cache, Configuration cfg, ISessionFactoryImplementor factory)
     : base(collection, cache, cfg, factory)
 {
     _cascadeDeleteEnabled = collection.Key.IsCascadeDeleteEnabled && factory.Dialect.SupportsCascadeDelete;
     _keyIsNullable        = collection.Key.IsNullable;
     _keyIsUpdateable      = collection.Key.IsUpdateable;
 }
コード例 #4
0
        private void BindManyToMany(HbmManyToMany manyToManyMapping, Mapping.Collection model)
        {
            var manyToMany = new ManyToOne(model.CollectionTable);

            model.Element = manyToMany;
            new ValuePropertyBinder(manyToMany, Mappings).BindSimpleValue(manyToManyMapping,
                                                                          Mapping.Collection.DefaultElementColumnName, false);
            InitOuterJoinFetchSetting(manyToManyMapping, manyToMany);
            var restrictedLaziness = manyToManyMapping.lazySpecified ? manyToManyMapping.lazy : (HbmRestrictedLaziness?)null;

            InitLaziness(restrictedLaziness, manyToMany, true);

            if (!string.IsNullOrEmpty(manyToManyMapping.propertyref))
            {
                manyToMany.ReferencedPropertyName = manyToManyMapping.propertyref;
            }

            manyToMany.ReferencedEntityName = GetEntityName(manyToManyMapping, mappings);

            manyToMany.IsIgnoreNotFound = manyToManyMapping.NotFoundMode == HbmNotFoundMode.Ignore;

            if (!string.IsNullOrEmpty(manyToManyMapping.foreignkey))
            {
                manyToMany.ForeignKeyName = manyToManyMapping.foreignkey;
            }
            BindManyToManySubelements(manyToManyMapping, model);
        }
コード例 #5
0
        private void BindKey(HbmKey keyMapping, Mapping.Collection model)
        {
            if (keyMapping == null)
            {
                return;
            }
            string    propRef = model.ReferencedPropertyName;
            IKeyValue keyValue;

            if (propRef == null)
            {
                keyValue = model.Owner.Identifier;
            }
            else
            {
                keyValue = (IKeyValue)model.Owner.GetProperty(propRef).Value;
            }
            var key = new DependantValue(model.CollectionTable, keyValue)
            {
                IsCascadeDeleteEnabled = keyMapping.ondelete == HbmOndelete.Cascade
            };

            new ValuePropertyBinder(key, Mappings).BindSimpleValue(keyMapping, Mapping.Collection.DefaultKeyColumnName, model.IsOneToMany);

            if (key.Type.ReturnedClass.IsArray)
            {
                throw new MappingException("illegal use of an array as an identifier (arrays don't reimplement Equals)");
            }
            model.Key = key;

            key.SetNullable(!keyMapping.IsNullable.HasValue || keyMapping.IsNullable.Value);
            key.SetUpdateable(!keyMapping.IsUpdatable.HasValue || keyMapping.IsUpdatable.Value);
            BindForeignKey(keyMapping.foreignkey, key);
        }
コード例 #6
0
 private static void PreCollectionSecondPass(Mapping.Collection collection)
 {
     if (log.IsDebugEnabled)
     {
         log.Debug("Second pass for collection: " + collection.Role);
     }
 }
コード例 #7
0
        private void HandleCustomSQL(ICollectionSqlsMapping collection, Mapping.Collection model)
        {
            var sqlInsert = collection.SqlInsert;

            if (sqlInsert != null)
            {
                bool callable = sqlInsert.callableSpecified && sqlInsert.callable;
                model.SetCustomSQLInsert(sqlInsert.Text.LinesToString(), callable, GetResultCheckStyle(sqlInsert));
            }

            var sqlDelete = collection.SqlDelete;

            if (sqlDelete != null)
            {
                bool callable = sqlDelete.callableSpecified && sqlDelete.callable;
                model.SetCustomSQLDelete(sqlDelete.Text.LinesToString(), callable, GetResultCheckStyle(sqlDelete));
            }

            var sqlUpdate = collection.SqlUpdate;

            if (sqlUpdate != null)
            {
                bool callable = sqlUpdate.callableSpecified && sqlUpdate.callable;
                model.SetCustomSQLUpdate(sqlUpdate.Text.LinesToString(), callable, GetResultCheckStyle(sqlUpdate));
            }

            var sqlDeleteAll = collection.SqlDeleteAll;

            if (sqlDeleteAll != null)
            {
                bool callable = sqlDeleteAll.callableSpecified && sqlDeleteAll.callable;
                model.SetCustomSQLDeleteAll(sqlDeleteAll.Text.LinesToString(), callable, GetResultCheckStyle(sqlDeleteAll));
            }
        }
コード例 #8
0
        private void InitLaziness(ICollectionPropertiesMapping collectionMapping, Mapping.Collection fetchable)
        {
            var lazyMapping = collectionMapping.Lazy;

            if (!lazyMapping.HasValue)
            {
                fetchable.IsLazy    = mappings.DefaultLazy;
                fetchable.ExtraLazy = false;
                return;
            }

            switch (lazyMapping.Value)
            {
            case HbmCollectionLazy.True:
                fetchable.IsLazy = true;
                break;

            case HbmCollectionLazy.False:
                fetchable.IsLazy    = false;
                fetchable.ExtraLazy = false;
                break;

            case HbmCollectionLazy.Extra:
                fetchable.IsLazy    = true;
                fetchable.ExtraLazy = true;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #9
0
        private void BindManyToManySubelements(HbmManyToMany manyToManyMapping, Mapping.Collection collection)
        {
            // Bind the where
            string whereCondition = string.IsNullOrEmpty(manyToManyMapping.where) ? null : manyToManyMapping.where;

            collection.ManyToManyWhere = whereCondition;

            // Bind the order-by
            string orderFragment = string.IsNullOrEmpty(manyToManyMapping.orderby) ? null : manyToManyMapping.orderby;

            collection.ManyToManyOrdering = orderFragment;

            // Bind the filters
            var filters    = manyToManyMapping.filter;
            var hasFilters = filters != null && filters.Length > 0;

            if ((hasFilters || whereCondition != null) && collection.FetchMode == FetchMode.Join &&
                collection.Element.FetchMode != FetchMode.Join)
            {
                throw new MappingException(
                          string.Format(
                              "many-to-many defining filter or where without join fetching not valid within collection using join fetching [{0}]",
                              collection.Role));
            }

            new FiltersBinder(collection, Mappings).Bind(filters, collection.AddManyToManyFilter);
        }
コード例 #10
0
 private static void BindCache(HbmCache cacheSchema, Mapping.Collection collection)
 {
     if (cacheSchema != null)
     {
         collection.CacheConcurrencyStrategy = cacheSchema.usage.ToCacheConcurrencyStrategy();
         collection.CacheRegionName          = cacheSchema.region;
     }
 }
コード例 #11
0
ファイル: Mappings.cs プロジェクト: ImanRezaeipour/GTS
 /// <summary>
 ///
 /// </summary>
 /// <param name="collection"></param>
 public void AddCollection(Mapping.Collection collection)
 {
     if (collections.ContainsKey(collection.Role))
     {
         throw new DuplicateMappingException("collection role", collection.Role);
     }
     collections[collection.Role] = collection;
 }
コード例 #12
0
 private void AddCollectionSecondPass(XmlNode node, Mapping.Collection model, IDictionary <string, MetaAttribute> inheritedMetas)
 {
     mappings.AddSecondPass(delegate(IDictionary <string, PersistentClass> persistentClasses)
     {
         PreCollectionSecondPass(model);
         BindCollectionSecondPass(node, model, persistentClasses, inheritedMetas);
         PostCollectionSecondPass(model);
     });
 }
コード例 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="collection"></param>
        public void AddCollection(Mapping.Collection collection)
        {
            object old = collections[collection.Role];

            if (old != null)
            {
                log.Warn("duplicate collection role: " + collection.Role);
            }
            collections[collection.Role] = collection;
        }
コード例 #14
0
        public static ICollectionPersister Create(System.Type persisterClass, Mapping.Collection model,
                                                  ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, Configuration cfg)
        {
            ConstructorInfo pc;
            var             use4Parameters = false;

            try
            {
                pc = persisterClass.GetConstructor(CollectionPersisterConstructorArgs);
                if (pc == null)
                {
                    use4Parameters = true;
                    pc             = persisterClass.GetConstructor(CollectionPersisterConstructor2Args);
                }
            }
            catch (Exception e)
            {
                throw new MappingException("Could not get constructor for " + persisterClass.Name, e);
            }
            if (pc == null)
            {
                var messageBuilder = new StringBuilder();
                messageBuilder.AppendLine("Could not find a public constructor for " + persisterClass.Name + ";");
                messageBuilder.AppendLine("- The ctor may have " + CollectionPersisterConstructorArgs.Length + " parameters of types (in order):");
                System.Array.ForEach(CollectionPersisterConstructorArgs, t => messageBuilder.AppendLine(t.FullName));
                messageBuilder.AppendLine();
                messageBuilder.AppendLine("- The ctor may have " + CollectionPersisterConstructor2Args.Length + " parameters of types (in order):");
                System.Array.ForEach(CollectionPersisterConstructor2Args, t => messageBuilder.AppendLine(t.FullName));
                throw new MappingException(messageBuilder.ToString());
            }
            try
            {
                if (!use4Parameters)
                {
                    return((ICollectionPersister)pc.Invoke(new object[] { model, cache, factory }));
                }
                return((ICollectionPersister)pc.Invoke(new object[] { model, cache, cfg, factory }));
            }
            catch (TargetInvocationException tie)
            {
                Exception e = tie.InnerException;
                if (e is HibernateException)
                {
                    throw e;
                }
                else
                {
                    throw new MappingException("Could not instantiate collection persister " + persisterClass.Name, e);
                }
            }
            catch (Exception e)
            {
                throw new MappingException("Could not instantiate collection persister " + persisterClass.Name, e);
            }
        }
 private static string searchMappedBy(PersistentClass referencedClass, Mapping.Collection collectionValue)
 {
     foreach (var property in referencedClass.PropertyIterator)
     {
         //should probably not care if order is same...
         if (property.Value.ColumnIterator.SequenceEqual(collectionValue.Key.ColumnIterator))
         {
             return(property.Name);
         }
     }
     return(null);
 }
コード例 #16
0
        private void BindManyToManySubelements(Mapping.Collection collection, XmlNode manyToManyNode)
        {
            // Bind the where
            XmlAttribute where = manyToManyNode.Attributes["where"];
            string whereCondition = where == null ? null : where.Value;

            collection.ManyToManyWhere = whereCondition;

            // Bind the order-by
            XmlAttribute order         = manyToManyNode.Attributes["order-by"];
            string       orderFragment = order == null ? null : order.Value;

            collection.ManyToManyOrdering = orderFragment;

            // Bind the filters
            if ((manyToManyNode.SelectSingleNode(HbmConstants.nsFilter, namespaceManager) != null ||
                 whereCondition != null) &&
                collection.FetchMode == FetchMode.Join &&
                collection.Element.FetchMode != FetchMode.Join)
            {
                throw new MappingException(
                          "many-to-many defining filter or where without join fetching " +
                          "not valid within collection using join fetching [" + collection.Role + "]"
                          );
            }
            foreach (XmlNode filterElement in manyToManyNode.SelectNodes(HbmConstants.nsFilter, namespaceManager))
            {
                string name      = XmlHelper.GetAttributeValue(filterElement, "name");
                string condition = filterElement.InnerText.Trim();
                if (StringHelper.IsEmpty(condition))
                {
                    condition = XmlHelper.GetAttributeValue(filterElement, "condition");
                }
                if (StringHelper.IsEmpty(condition))
                {
                    condition = mappings.GetFilterDefinition(name).DefaultFilterCondition;
                }
                if (condition == null)
                {
                    throw new MappingException("no filter condition found for filter: " + name);
                }
                log.Debug(
                    "Applying many-to-many filter [" + name +
                    "] as [" + condition +
                    "] to role [" + collection.Role + "]"
                    );
                collection.AddManyToManyFilter(name, condition);
            }
        }
コード例 #17
0
 public static ICollectionPersister CreateCollectionPersister(Mapping.Collection model, ISessionFactoryImplementor factory)
 {
     System.Type persisterClass = model.CollectionPersisterClass;
     if (persisterClass == null)
     {
         // default behaviour
         return(model.IsOneToMany ?
                (ICollectionPersister) new OneToManyPersister(model, factory) :
                (ICollectionPersister) new BasicCollectionPersister(model, factory));
     }
     else
     {
         return(Create(persisterClass, model, factory));
     }
 }
コード例 #18
0
        private void BindManyToAny(HbmManyToAny manyToAnyMapping, Mapping.Collection model)
        {
            var any = new Any(model.CollectionTable);

            model.Element          = any;
            any.IdentifierTypeName = manyToAnyMapping.idtype;
            new TypeBinder(any, Mappings).Bind(manyToAnyMapping.idtype);
            BindAnyMeta(manyToAnyMapping, any);
            new ColumnsBinder(any, Mappings).Bind(manyToAnyMapping.Columns, true,
                                                  () =>
                                                  new HbmColumn
            {
                name = mappings.NamingStrategy.PropertyToColumnName(manyToAnyMapping.column1)
            });
        }
コード例 #19
0
 private String GetMiddleTableName(Mapping.Collection value, String entityName)
 {
     // We check how Hibernate maps the collection.
     if (value.Element is OneToMany && !value.IsInverse)
     {
         // This must be a @JoinColumn+@OneToMany mapping. Generating the table name, as Hibernate doesn't use a
         // middle table for mapping this relation.
         String refEntName = MappingTools.getReferencedEntityName(value.Element);
         return(entityName.Substring(entityName.LastIndexOf(".") + 1) + "_" +
                refEntName.Substring(refEntName.LastIndexOf(".") + 1));
     }
     else
     {
         // Hibernate uses a middle table for mapping this relation, so we get it's name directly.
         return(value.CollectionTable.Name);
     }
 }
コード例 #20
0
        private void BindElement(HbmElement elementMapping, Mapping.Collection model)
        {
            var element = new SimpleValue(model.CollectionTable);

            model.Element = element;
            if (model.IsGeneric)
            {
                switch (model.GenericArguments.Length)
                {
                case 1:
                    // a collection with a generic type parameter
                    element.TypeName = model.GenericArguments[0].AssemblyQualifiedName;
                    break;

                case 2:
                    // a map (IDictionary) with 2 parameters
                    element.TypeName = model.GenericArguments[1].AssemblyQualifiedName;
                    break;
                }
            }
            new ValuePropertyBinder(element, Mappings).BindSimpleValue(elementMapping, Mapping.Collection.DefaultKeyColumnName, true);
        }
コード例 #21
0
        /**
         * @param mainGenerator Main generator, giving access to configuration and the basic mapper.
         * @param propertyValue Value of the collection, as mapped by Hibernate.
         * @param currentMapper Mapper, to which the appropriate {@link org.hibernate.envers.entities.mapper.PropertyMapper}
         * will be added.
         * @param referencingEntityName Name of the entity that owns this collection.
         * @param xmlMappingData In case this collection requires a middle table, additional mapping documents will
         * be created using this object.
         * @param propertyAuditingData Property auditing (meta-)data. Among other things, holds the name of the
         * property that references the collection in the referencing entity, the user data for middle (join)
         * table and the value of the <code>@MapKey</code> annotation, if there was one.
         */
        public CollectionMetadataGenerator(AuditMetadataGenerator mainGenerator,
                                           Mapping.Collection propertyValue, ICompositeMapperBuilder currentMapper,
                                           String referencingEntityName, EntityXmlMappingData xmlMappingData,
                                           PropertyAuditingData propertyAuditingData)
        {
            this.mainGenerator         = mainGenerator;
            this.propertyValue         = propertyValue;
            this.currentMapper         = currentMapper;
            this.referencingEntityName = referencingEntityName;
            this.xmlMappingData        = xmlMappingData;
            this.propertyAuditingData  = propertyAuditingData;

            this.propertyName = propertyAuditingData.Name;

            referencingEntityConfiguration = mainGenerator.EntitiesConfigurations[referencingEntityName];
            if (referencingEntityConfiguration == null)
            {
                throw new MappingException("Unable to read auditing configuration for " + referencingEntityName + "!");
            }

            referencedEntityName = MappingTools.getReferencedEntityName(propertyValue.Element);
        }
コード例 #22
0
        private string getMappedBy(Mapping.Collection collectionValue)
        {
            var referencedClass = _mainGenerator.Cfg.GetClassMapping(MappingTools.ReferencedEntityName(collectionValue.Element));
            var mappedBy        = searchMappedBy(referencedClass, collectionValue);

            if (mappedBy == null)
            {
                log.Debug("Going to search the mapped by attribute for " + _propertyName + " in superclasses of entity: " + referencedClass.ClassName);
                var tempClass = referencedClass;
                while (mappedBy == null && tempClass.Superclass != null)
                {
                    log.Debug("Searching in superclass: " + tempClass.Superclass.ClassName);
                    mappedBy  = searchMappedBy(tempClass.Superclass, collectionValue);
                    tempClass = tempClass.Superclass;
                }
            }
            if (mappedBy == null)
            {
                throw new MappingException("Cannot find the inverse side for " + _propertyName + " in " + _referencingEntityName + "!");
            }
            return(mappedBy);
        }
コード例 #23
0
        private static void PostCollectionSecondPass(Mapping.Collection collection)
        {
            collection.CreateAllKeys();

            if (log.IsDebugEnabled)
            {
                string msg = "Mapped collection key: " + string.Join(",", collection.Key.ColumnIterator.Select(c => c.Text).ToArray());
                if (collection.IsIndexed)
                {
                    msg += ", index: " + string.Join(",", ((IndexedCollection)collection).Index.ColumnIterator.Select(c => c.Text).ToArray());
                }
                if (collection.IsOneToMany)
                {
                    msg += ", one-to-many: " + collection.Element.Type.Name;
                }
                else
                {
                    msg += ", element: " + string.Join(",", collection.Element.ColumnIterator.Select(c => c.Text).ToArray());
                    msg += ", type: " + collection.Element.Type.Name;
                }
                log.Debug(msg);
            }
        }
コード例 #24
0
        public void ConfigureCacheOfCollection()
        {
            Configuration configure = new Configuration().Configure();

            configure.AddResource("NHibernate.Test.CfgTest.Loquacious.EntityToCache.hbm.xml", GetType().Assembly);

            configure.EntityCache <EntityToCache>(ce =>
            {
                ce.Strategy   = EntityCacheUsage.NonStrictReadWrite;
                ce.RegionName = "MyRegion";
                ce.Collection(e => e.Elements, cc =>
                {
                    cc.RegionName = "MyCollectionRegion";
                    cc.Strategy   =
                        EntityCacheUsage.NonStrictReadWrite;
                });
            });

            Mapping.Collection pc = configure.GetCollectionMapping("NHibernate.Test.CfgTest.Loquacious.EntityToCache.Elements");
            Assert.That(pc.CacheConcurrencyStrategy,
                        Is.EqualTo(EntityCacheUsageParser.ToString(EntityCacheUsage.NonStrictReadWrite)));
            Assert.That(pc.CacheRegionName, Is.EqualTo("MyCollectionRegion"));
        }
コード例 #25
0
        private static void PostCollectionSecondPass(Mapping.Collection collection)
        {
            collection.CreateAllKeys();

            if (log.IsDebugEnabled)
            {
                string msg = "Mapped collection key: " + Columns(collection.Key);
                if (collection.IsIndexed)
                {
                    msg += ", index: " + Columns(((IndexedCollection)collection).Index);
                }
                if (collection.IsOneToMany)
                {
                    msg += ", one-to-many: " + collection.Element.Type.Name;
                }
                else
                {
                    msg += ", element: " + Columns(collection.Element);
                    msg += ", type: " + collection.Element.Type.Name;
                }
                log.Debug(msg);
            }
        }
コード例 #26
0
        public void CollectionFetchVsLoad()
        {
            IStatistics stats = Sfi.Statistics;

            stats.Clear();

            ISession     s      = OpenSession();
            ITransaction tx     = s.BeginTransaction();
            Continent    europe = FillDb(s);

            tx.Commit();
            s.Clear();

            tx = s.BeginTransaction();
            Assert.AreEqual(0, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount);
            Continent europe2 = s.Get <Continent>(europe.Id);

            Assert.AreEqual(0, stats.CollectionLoadCount, "Lazy true: no collection should be loaded");
            Assert.AreEqual(0, stats.CollectionFetchCount);

            int cc = europe2.Countries.Count;

            Assert.AreEqual(1, stats.CollectionLoadCount);
            Assert.AreEqual(1, stats.CollectionFetchCount, "Explicit fetch of the collection state");
            tx.Commit();
            s.Close();

            s  = OpenSession();
            tx = s.BeginTransaction();
            stats.Clear();
            europe = FillDb(s);
            tx.Commit();
            s.Clear();
            tx = s.BeginTransaction();
            Assert.AreEqual(0, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount);

            europe2 = s.CreateQuery("from Continent a join fetch a.Countries where a.id = " + europe.Id).UniqueResult <Continent>();
            Assert.AreEqual(1, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount, "collection should be loaded in the same query as its parent");
            tx.Commit();
            s.Close();

            Mapping.Collection coll = cfg.GetCollectionMapping("NHibernate.Test.Stats.Continent.Countries");
            coll.FetchMode = FetchMode.Join;
            coll.IsLazy    = false;
            ISessionFactory sf = cfg.BuildSessionFactory();

            stats = sf.Statistics;
            stats.Clear();
            stats.IsStatisticsEnabled = true;
            s      = sf.OpenSession();
            tx     = s.BeginTransaction();
            europe = FillDb(s);
            tx.Commit();
            s.Clear();
            tx = s.BeginTransaction();
            Assert.AreEqual(0, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount);

            europe2 = s.Get <Continent>(europe.Id);
            Assert.AreEqual(1, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount,
                            "Should do direct load, not indirect second load when lazy false and JOIN");
            tx.Commit();
            s.Close();
            sf.Close();

            coll           = cfg.GetCollectionMapping("NHibernate.Test.Stats.Continent.Countries");
            coll.FetchMode = FetchMode.Select;
            coll.IsLazy    = false;
            sf             = cfg.BuildSessionFactory();
            stats          = sf.Statistics;
            stats.Clear();
            stats.IsStatisticsEnabled = true;
            s      = sf.OpenSession();
            tx     = s.BeginTransaction();
            europe = FillDb(s);
            tx.Commit();
            s.Clear();
            tx = s.BeginTransaction();
            Assert.AreEqual(0, stats.CollectionLoadCount);
            Assert.AreEqual(0, stats.CollectionFetchCount);
            europe2 = s.Get <Continent>(europe.Id);
            Assert.AreEqual(1, stats.CollectionLoadCount);
            Assert.AreEqual(1, stats.CollectionFetchCount, "Should do explicit collection load, not part of the first one");
            foreach (Country country in europe2.Countries)
            {
                s.Delete(country);
            }
            CleanDb(s);
            tx.Commit();
            s.Close();
        }
コード例 #27
0
		public CollectionSecondPass(Mappings mappings, Mapping.Collection collection)
		{
			this.collection = collection;
			this.mappings = mappings;
		}
コード例 #28
0
 public BasicCollectionPersister(Mapping.Collection collection, ICacheConcurrencyStrategy cache, Configuration cfg, ISessionFactoryImplementor factory)
     : base(collection, cache, cfg, factory)
 {
 }
コード例 #29
0
			public AbstractSecondPass( XmlNode node, Mappings mappings, Mapping.Collection collection )
			{
				this.node = node;
				this.collection = collection;
				this.mappings = mappings;
			}
コード例 #30
0
        private void BindCompositeElement(HbmCompositeElement compositeElementMapping, Mapping.Collection model, IDictionary <string, MetaAttribute> inheritedMetas)
        {
            var component = new Component(model);

            model.Element = component;
            BindComponent(compositeElementMapping, component, null, null, model.Role + ".element", true, inheritedMetas);
        }
コード例 #31
0
        /// <remarks>
        /// Called for all collections
        /// </remarks>
        private void BindCollectionSecondPass(XmlNode node, Mapping.Collection model,
                                              IDictionary <string, PersistentClass> persistentClasses, IDictionary <string, MetaAttribute> inheritedMetas)
        {
            if (model.IsOneToMany)
            {
                OneToMany       oneToMany            = (OneToMany)model.Element;
                string          associatedEntityName = oneToMany.ReferencedEntityName;
                PersistentClass persistentClass;
                if (persistentClasses.TryGetValue(associatedEntityName, out persistentClass) == false)
                {
                    throw new MappingException("Association references unmapped class: " + associatedEntityName);
                }
                oneToMany.AssociatedClass = persistentClass;
                model.CollectionTable     = persistentClass.Table;

                if (log.IsInfoEnabled)
                {
                    log.Info("mapping collection: " + model.Role + " -> " + model.CollectionTable.Name);
                }
            }

            //CHECK
            XmlAttribute chNode = node.Attributes["check"];

            if (chNode != null)
            {
                model.CollectionTable.AddCheckConstraint(chNode.Value);
            }

            //contained elements:
            foreach (XmlNode subnode in node.ChildNodes)
            {
                //I am only concerned with elements that are from the nhibernate namespace
                if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
                {
                    continue;
                }

                string name = subnode.LocalName;                 //.Name;

                if ("key".Equals(name) || "generated-key".Equals(name))
                {
                    string    propRef = model.ReferencedPropertyName;
                    IKeyValue keyValue;
                    if (propRef == null)
                    {
                        keyValue = model.Owner.Identifier;
                    }
                    else
                    {
                        keyValue = (IKeyValue)model.Owner.GetProperty(propRef).Value;
                    }
                    DependantValue key = new DependantValue(model.CollectionTable, keyValue);
                    if (subnode.Attributes["on-delete"] != null)
                    {
                        key.IsCascadeDeleteEnabled = "cascade".Equals(subnode.Attributes["on-delete"].Value);
                    }
                    BindSimpleValue(subnode, key, model.IsOneToMany, Mapping.Collection.DefaultKeyColumnName);
                    if (key.Type.ReturnedClass.IsArray)
                    {
                        throw new MappingException("illegal use of an array as an identifier (arrays don't reimplement Equals)");
                    }
                    model.Key = key;


                    XmlAttribute notNull = subnode.Attributes["not-null"];
                    key.SetNullable(notNull == null || IsFalse(notNull.Value));
                    XmlAttribute updateable = subnode.Attributes["update"];
                    key.SetUpdateable(updateable == null || IsTrue(updateable.Value));
                }
                else if ("element".Equals(name))
                {
                    var elt = new SimpleValue(model.CollectionTable);
                    model.Element = elt;
                    if (model.IsGeneric)
                    {
                        switch (model.GenericArguments.Length)
                        {
                        case 1:
                            // a collection with a generic type parameter
                            elt.TypeName = model.GenericArguments[0].AssemblyQualifiedName;
                            break;

                        case 2:
                            // a map (IDictionary) with 2 parameters
                            elt.TypeName = model.GenericArguments[1].AssemblyQualifiedName;
                            break;
                        }
                    }
                    BindSimpleValue(subnode, elt, true, Mapping.Collection.DefaultElementColumnName);
                }
                else if ("many-to-many".Equals(name))
                {
                    ManyToOne element = new ManyToOne(model.CollectionTable);
                    model.Element = element;
                    BindManyToOne(subnode, element, Mapping.Collection.DefaultElementColumnName, false);
                    BindManyToManySubelements(model, subnode);
                }
                else if ("composite-element".Equals(name))
                {
                    Component element = new Component(model);
                    model.Element = element;
                    BindComponent(subnode, element, null, null, null, model.Role + ".element", true, inheritedMetas);
                }
                else if ("many-to-any".Equals(name))
                {
                    Any element = new Any(model.CollectionTable);
                    model.Element = element;
                    BindAny(subnode, element, true);
                }
                else if ("jcs-cache".Equals(name) || "cache".Equals(name))
                {
                    XmlAttribute usageNode = subnode.Attributes["usage"];
                    model.CacheConcurrencyStrategy = (usageNode != null) ? usageNode.Value : null;
                    XmlAttribute regionNode = subnode.Attributes["region"];
                    model.CacheRegionName = (regionNode != null) ? regionNode.Value : null;
                }
            }
        }
コード例 #32
0
        /// <remarks>
        /// Called for all collections. <paramref name="containingType" /> parameter
        /// was added in NH to allow for reflection related to generic types.
        /// </remarks>
        private void BindCollection(XmlNode node, Mapping.Collection model, string className,
                                    string path, System.Type containingType, IDictionary <string, MetaAttribute> inheritedMetas)
        {
            // ROLENAME
            model.Role = StringHelper.Qualify(className, path);
            // TODO: H3.1 has just collection.setRole(path) here - why?

            XmlAttribute inverseNode = node.Attributes["inverse"];

            if (inverseNode != null)
            {
                model.IsInverse = StringHelper.BooleanValue(inverseNode.Value);
            }

            // TODO: H3.1 - not ported: mutable
            XmlAttribute olNode = node.Attributes["optimistic-lock"];

            model.IsOptimisticLocked = olNode == null || "true".Equals(olNode.Value);

            XmlAttribute orderNode = node.Attributes["order-by"];

            if (orderNode != null)
            {
                model.OrderBy = orderNode.Value;
            }
            XmlAttribute whereNode = node.Attributes["where"];

            if (whereNode != null)
            {
                model.Where = whereNode.Value;
            }
            XmlAttribute batchNode = node.Attributes["batch-size"];

            if (batchNode != null)
            {
                model.BatchSize = int.Parse(batchNode.Value);
            }

            // PERSISTER
            XmlAttribute persisterNode = node.Attributes["persister"];

            if (persisterNode == null)
            {
                //persister = CollectionPersisterImpl.class;
            }
            else
            {
                model.CollectionPersisterClass = ClassForNameChecked(
                    persisterNode.Value, mappings,
                    "could not instantiate collection persister class: {0}");
            }

            XmlAttribute typeNode = node.Attributes["collection-type"];

            if (typeNode != null)
            {
                string  typeName = typeNode.Value;
                TypeDef typeDef  = mappings.GetTypeDef(typeName);
                if (typeDef != null)
                {
                    model.TypeName       = typeDef.TypeClass;
                    model.TypeParameters = typeDef.Parameters;
                }
                else
                {
                    model.TypeName = FullQualifiedClassName(typeName, mappings);
                }
            }

            // FETCH STRATEGY
            InitOuterJoinFetchSetting(node, model);

            if ("subselect".Equals(XmlHelper.GetAttributeValue(node, "fetch")))
            {
                model.IsSubselectLoadable = true;
                model.Owner.HasSubselectLoadableCollections = true;
            }

            // LAZINESS
            InitLaziness(node, model, "true", mappings.DefaultLazy);
            XmlAttribute lazyNode = node.Attributes["lazy"];

            if (lazyNode != null && "extra".Equals(lazyNode.Value))
            {
                model.IsLazy    = true;
                model.ExtraLazy = true;
            }

            XmlNode oneToManyNode = node.SelectSingleNode(HbmConstants.nsOneToMany, namespaceManager);

            if (oneToManyNode != null)
            {
                OneToMany oneToMany = new OneToMany(model.Owner);
                model.Element = oneToMany;
                BindOneToMany(oneToManyNode, oneToMany);
                //we have to set up the table later!! yuck
            }
            else
            {
                //TABLE
                XmlAttribute tableNode = node.Attributes["table"];
                string       tableName;
                if (tableNode != null)
                {
                    tableName = mappings.NamingStrategy.TableName(tableNode.Value);
                }
                else
                {
                    tableName = mappings.NamingStrategy.PropertyToTableName(className, path);
                }
                XmlAttribute schemaNode  = node.Attributes["schema"];
                string       schema      = schemaNode == null ? mappings.SchemaName : schemaNode.Value;
                XmlAttribute catalogNode = node.Attributes["catalog"];
                string       catalog     = catalogNode == null ? mappings.CatalogName : catalogNode.Value;

                XmlAttribute actionNode = node.Attributes["schema-action"];
                string       action     = actionNode == null ? "all" : actionNode.Value;

                model.CollectionTable = mappings.AddTable(schema, catalog, tableName, null, false, action);

                log.InfoFormat("Mapping collection: {0} -> {1}", model.Role, model.CollectionTable.Name);
            }

            //SORT
            XmlAttribute sortedAtt = node.Attributes["sort"];

            // unsorted, natural, comparator.class.name
            if (sortedAtt == null || sortedAtt.Value.Equals("unsorted"))
            {
                model.IsSorted = false;
            }
            else
            {
                model.IsSorted = true;
                if (!sortedAtt.Value.Equals("natural"))
                {
                    string comparatorClassName = FullQualifiedClassName(sortedAtt.Value, mappings);
                    model.ComparerClassName = comparatorClassName;
                }
            }

            //ORPHAN DELETE (used for programmer error detection)
            XmlAttribute cascadeAtt = node.Attributes["cascade"];

            if (cascadeAtt != null && cascadeAtt.Value.IndexOf("delete-orphan") >= 0)
            {
                model.HasOrphanDelete = true;
            }

            bool?isGeneric = null;

            XmlAttribute genericAtt = node.Attributes["generic"];

            if (genericAtt != null)
            {
                isGeneric = bool.Parse(genericAtt.Value);
            }

            System.Type collectionType = null;

            if (!isGeneric.HasValue && containingType != null)
            {
                collectionType = GetPropertyType(node, containingType, GetPropertyName(node));
                isGeneric      = collectionType.IsGenericType;
            }

            model.IsGeneric = isGeneric ?? false;

            if (model.IsGeneric)
            {
                // Determine the generic arguments using reflection
                if (collectionType == null)
                {
                    collectionType = GetPropertyType(node, containingType, GetPropertyName(node));
                }
                System.Type[] genericArguments = collectionType.GetGenericArguments();
                model.GenericArguments = genericArguments;
            }

            HandleCustomSQL(node, model);

            //set up second pass
            if (model is List)
            {
                AddListSecondPass(node, (List)model, inheritedMetas);
            }

            else if (model is Map)
            {
                AddMapSecondPass(node, (Map)model, inheritedMetas);
            }

            else if (model is Set)
            {
                AddSetSecondPass(node, (Set)model, inheritedMetas);
            }

            else if (model is IdentifierCollection)
            {
                AddIdentifierCollectionSecondPass(node, (IdentifierCollection)model, inheritedMetas);
            }

            else
            {
                AddCollectionSecondPass(node, model, inheritedMetas);
            }

            foreach (XmlNode filter in node.SelectNodes(HbmConstants.nsFilter, namespaceManager))
            {
                ParseFilter(filter, model);
            }

            XmlNode loader = node.SelectSingleNode(HbmConstants.nsLoader, namespaceManager);

            if (loader != null)
            {
                model.LoaderName = XmlHelper.GetAttributeValue(loader, "query-ref");
            }

            XmlNode key = node.SelectSingleNode(HbmConstants.nsKey, namespaceManager);

            if (key != null)
            {
                model.ReferencedPropertyName = XmlHelper.GetAttributeValue(key, "property-ref");
            }
        }