private void UpdateChildrenDependencies(int batchNumber, AbstractEntityInsertAction action) { var propertyValues = action.State; var propertyTypes = action.Persister.EntityMetamodel?.PropertyTypes; if (propertyTypes == null) { log.Warn( "Entity {0} persister does not provide meta-data: if there is dependent entities providing " + "meta-data, they may get batched before this one and cause a failure.", action.EntityName); return; } var sessionFactory = action.Session.Factory; for (var i = 0; i < propertyValues.Length; i++) { var type = propertyTypes[i]; if (!type.IsCollectionType) { continue; } var collectionType = (CollectionType)type; var collectionPersister = sessionFactory.GetCollectionPersister(collectionType.Role); if (collectionPersister.IsManyToMany || !collectionPersister.ElementType.IsEntityType) { continue; } var children = propertyValues[i] as IEnumerable; if (children == null) { continue; } foreach (var child in children) { if (child == null) { continue; } int latestDependency; if (_entityBatchDependency.TryGetValue(child, out latestDependency) && latestDependency > batchNumber) { continue; } _entityBatchDependency[child] = batchNumber; } } }
private void AddToBatch(int batchNumber, AbstractEntityInsertAction action) { List <AbstractEntityInsertAction> actions; if (!_actionBatches.TryGetValue(batchNumber, out actions)) { actions = new List <AbstractEntityInsertAction>(); _actionBatches[batchNumber] = actions; } actions.Add(action); }
private bool RequireNewBatch(AbstractEntityInsertAction action, int latestBatchNumberForType) { // This method assumes the original action list is already sorted in order to respect dependencies. var propertyValues = action.State; var propertyTypes = action.Persister.EntityMetamodel?.PropertyTypes; if (propertyTypes == null) { log.Info( "Entity {0} persister does not provide meta-data, giving up batching grouping optimization for this entity.", action.EntityName); // Cancel grouping optimization for this entity. return(true); } int latestDependency; if (_entityBatchDependency.TryGetValue(action.Instance, out latestDependency) && latestDependency > latestBatchNumberForType) { return(true); } for (var i = 0; i < propertyValues.Length; i++) { var value = propertyValues[i]; var type = propertyTypes[i]; if (type.IsEntityType && value != null && // If the value is not initialized, it is a proxy with pending load from database, // so it can only be an already persisted entity. It can not have its own pending // insertion batch. So there is no need to seek for it, and it avoids initializing // it by searching it in a dictionary. Fixes #1338. NHibernateUtil.IsInitialized(value)) { // find the batch number associated with the current association, if any. int associationBatchNumber; if (_entityBatchNumber.TryGetValue(value, out associationBatchNumber) && associationBatchNumber > latestBatchNumberForType) { return(true); } } } return(false); }
private bool RequireNewBatch(AbstractEntityInsertAction action, int latestBatchNumberForType) { // This method assumes the original action list is already sorted in order to respect dependencies. var propertyValues = action.State; var propertyTypes = action.Persister.EntityMetamodel?.PropertyTypes; if (propertyTypes == null) { log.Info( "Entity {0} persister does not provide meta-data, giving up batching grouping optimization for this entity.", action.EntityName); // Cancel grouping optimization for this entity. return(true); } int latestDependency; if (_entityBatchDependency.TryGetValue(action.Instance, out latestDependency) && latestDependency > latestBatchNumberForType) { return(true); } for (var i = 0; i < propertyValues.Length; i++) { var value = propertyValues[i]; var type = propertyTypes[i]; if (type.IsEntityType && value != null) { // find the batch number associated with the current association, if any. int associationBatchNumber; if (_entityBatchNumber.TryGetValue(value, out associationBatchNumber) && associationBatchNumber > latestBatchNumberForType) { return(true); } } } return(false); }
private int GetBatchNumber(AbstractEntityInsertAction action, string entityName) { int batchNumber; if (_latestBatches.TryGetValue(entityName, out batchNumber)) { // There is already an existing batch for this type of entity. // Check to see if the latest batch is acceptable. if (!RequireNewBatch(action, batchNumber)) { return(batchNumber); } } // add an entry for this type of entity. // we can be assured that all referenced entities have already // been processed, // so specify that this entity is with the latest batch. // doing the batch number before adding the name to the list is // a faster way to get an accurate number. batchNumber = _actionBatches.Count; _latestBatches[entityName] = batchNumber; return(batchNumber); }
private void UpdateChildrenDependencies(int batchNumber, AbstractEntityInsertAction action) { var propertyValues = action.State; var propertyTypes = action.Persister.EntityMetamodel?.PropertyTypes; if (propertyTypes == null) { log.Warn( "Entity {0} persister does not provide meta-data: if there is dependent entities providing " + "meta-data, they may get batched before this one and cause a failure.", action.EntityName); return; } var sessionFactory = action.Session.Factory; for (var i = 0; i < propertyValues.Length; i++) { var type = propertyTypes[i]; if (!type.IsCollectionType) { continue; } var collectionType = (CollectionType)type; var collectionPersister = sessionFactory.GetCollectionPersister(collectionType.Role); if (collectionPersister.IsManyToMany || !collectionPersister.ElementType.IsEntityType) { continue; } var children = propertyValues[i] as IEnumerable; if (children == null) { continue; } foreach (var child in children) { if (child == null || // If the child is not initialized, it is a proxy with pending load from database, // so it can only be an already persisted entity. It can not have its own pending // insertion batch. So we do not need to keep track of the highest other batch on // which it depends. And this avoids initializing the proxy by searching it into // a dictionary. !NHibernateUtil.IsInitialized(child)) { continue; } int latestDependency; if (_entityBatchDependency.TryGetValue(child, out latestDependency) && latestDependency > batchNumber) { continue; } _entityBatchDependency[child] = batchNumber; } } }