And yes, I tried evicting the entities after deleting them with hql
with no success of preventing nh from creating deletes.
Here is a example of the implementation
public class MarketingPlanOneShotDeleteHandler :
IOneShotDeleteHandler
{
public Type ForEntity()
{
return typeof(MarketingPlan);
}
public Type[] ForChildEntities()
{
return new[]
{
typeof(MarketingPlanProduct)
,typeof(PlanFee)
,typeof(ProductRate)
,typeof(BaseProductBenefit)
,typeof(BenefitSpecification)
,typeof(BenefitStatement)
,typeof(BaseProductCoInsurance)
,typeof(BenefitLimit)
,typeof(BenefitDeductible)
,typeof(MarketingPlanFeature)
,typeof(CustomMarketingPlanFeature)
,typeof(PolicySupplierType)
,typeof(MarketingPlanBaseProduct)
};
}
public void Delete(ISession session, object entity)
{
var marketingPlan = (MarketingPlan)entity;
var allowedBaseProductsIds =
marketingPlan.AllowedBaseProducts.Select(x => x.Id).ToList();
#region "gather ids"
List<int> productIds = marketingPlan.Products.Select(x =>
x.Id).ToList();
List<int> productRateIds = marketingPlan.Products
.SelectMany(x => x.ProductRates.Select(r =>
r.Id)).ToList();
List<int> planFeeIds = marketingPlan.Products
.SelectMany(x => x.ProductRates
.SelectMany(r =>
r.AllFees.Select(f => f.Id))).ToList();
List<int> supplierTypeIds =
marketingPlan.PolicySupplierTypes.Select(x => x.Id).ToList();
List<int> planFeaturesIds =
marketingPlan.MarketingPlanFeatures.Select(x => x.Id).ToList();
List<int> customPlanFeaturesIds =
marketingPlan.CustomMarketingPlanFeatures.Select(x => x.Id).ToList();
List<int> benefitIds = marketingPlan.AllowedBaseProducts.
SelectMany(x => x.Benefits.Select(b =>
b.Id)).ToList();
List<int> benefitStatementsIds =
marketingPlan.AllowedBaseProducts
.SelectMany(b => b.Benefits
.SelectMany(bn =>
bn.BenefitStatements.Select(s => s.Id))).ToList();
List<int> benefitSpecificationsIds =
marketingPlan.AllowedBaseProducts
.SelectMany(b => b.Benefits
.SelectMany(bn =>
bn.BenefitSpecifications.Select(s => s.Id))).ToList();
List<int> coInsuranceIds =
marketingPlan.BaseProductCoInsurances.Select(x => x.Id).ToList();
List<int> limitIds = marketingPlan.BenefitLimits.Select(x
=> x.Id).ToList();
List<int> deductibleIds =
marketingPlan.BenefitDeductibles.Select(x => x.Id).ToList();
#endregion
var q = new List<IQuery>();
#region "MarketingPlanProductOneShotDeleteHandler"
//note: currently sql queries are not supported in multi
queries hence the implemenation
q.Add(session.CreateSQLQuery(
"delete from
vw_D_MarketingPlanBaseProductToProduct where BaseProductId in
(:baseProductIds)")
.SetParameterList("baseProductIds",
allowedBaseProductsIds));
q.Add(session.CreateQuery("delete PlanFee where
FullTermFeeId in (:planFeeIds)")
.SetParameterList("planFeeIds", planFeeIds));
q.Add(session.CreateQuery("delete ProductRate where
FullTermRateId in (:productRateIds)")
.SetParameterList("productRateIds",
productRateIds));
q.Add(session.CreateQuery("delete MarketingPlanProduct
where MktgPlanProductId in (:productIds)")
.SetParameterList("productIds", productIds));
#endregion
#region "BaseProducts"
q.Add(session.CreateQuery(
" delete BaseProductCoInsurance where
BaseProductCoInsuranceId in (:coInsuranceIds)")
.SetParameterList("coInsuranceIds",
coInsuranceIds));
q.Add(session.CreateQuery("delete BenefitLimit where
BenefitLimitId in (:benefitLimitIds)")
.SetParameterList("benefitLimitIds", limitIds));
q.Add(session.CreateSQLQuery(
"delete vw_D_BenefitDeductibleSupplierType where
BaseProductId in (:baseProductIds)")
.SetParameterList("baseProductIds",
allowedBaseProductsIds));
q.Add(session.CreateQuery("delete BenefitDeductible where
BenefitDeductibleId in (:deductibleIds)")
.SetParameterList("deductibleIds",
deductibleIds));
q.Add(session.CreateQuery("delete BenefitSpecification
where BenefitSpecId in (:benefitSpecificationsIds)")
.SetParameterList("benefitSpecificationsIds",
benefitSpecificationsIds));
q.Add(session.CreateQuery("delete BenefitStatement where
BenefitStatementId in (:benefitStatementsIds)")
.SetParameterList("benefitStatementsIds",
benefitStatementsIds));
q.Add(session.CreateQuery("delete BaseProductBenefit where
ProductBenefitId in (:benefitIds)")
.SetParameterList("benefitIds", benefitIds));
q.Add(session.CreateQuery("delete MarketingPlanBaseProduct
where BaseProductId in (:baseProductIds)")
.SetParameterList("baseProductIds",
allowedBaseProductsIds));
#endregion
q.Add(session.CreateQuery(
"delete CustomMarketingPlanFeature where
CustomPlanIndicatorsId in (:customPlanFeaturesIds)")
.SetParameterList("customPlanFeaturesIds",
customPlanFeaturesIds));
q.Add(session.CreateQuery("delete MarketingPlanFeature
where PlanIndicatorId in (:planFeaturesIds)")
.SetParameterList("planFeaturesIds",
planFeaturesIds));
q.Add(session.CreateQuery("delete PolicySupplierType where
PlcySupplierTypeId in (:supplierTypeIds)")
.SetParameterList("supplierTypeIds",
supplierTypeIds));
q.ForEach(query => query.ExecuteUpdate());
//now clean up so that NH would not executed deletes
itself
planFeeIds.ForEach(id =>
session.Evict(session.Load<PlanFee>(id)));
productRateIds.ForEach(id =>
session.Evict(session.Load<ProductRate>(id)));
productIds.ForEach(id =>
session.Evict(session.Load<MarketingPlanProduct>(id)));
coInsuranceIds.ForEach(id =>
session.Evict(session.Load<BaseProductCoInsurance>(id)));
limitIds.ForEach(id =>
session.Evict(session.Load<BenefitLimit>(id)));
deductibleIds.ForEach(id =>
session.Evict(session.Load<BenefitDeductible>(id)));
benefitStatementsIds.ForEach(id =>
session.Evict(session.Load<BenefitStatement>(id)));
benefitSpecificationsIds.ForEach(id =>
session.Evict(session.Load<BenefitSpecification>(id)));
benefitIds.ForEach(id =>
session.Evict(session.Load<BaseProductBenefit>(id)));
allowedBaseProductsIds.ForEach(id =>
session.Evict(session.Load<MarketingPlanBaseProduct>(id)));
customPlanFeaturesIds.ForEach(id =>
session.Evict(session.Load<CustomMarketingPlanFeature>(id)));
planFeaturesIds.ForEach(id =>
session.Evict(session.Load<MarketingPlanFeature>(id)));
supplierTypeIds.ForEach(id =>
session.Evict(session.Load<PolicySupplierType>(id)));
}
}
On Sep 20, 8:39 am, epitka <[email protected]> wrote:
> There is a IOneShotDeleteHandler interface that is apparently for
> deleting collections in one shot, hence the name. Instead of NH
> issuing delete statement for each item in the collection, one can
> implement this interface and than execute delete as one sees fit.
> Kinda like cascade deletes, but in NH rather than in db. There was one
> post on elegant code about it, but the implementation does not work as
> expected for us. It works fine for just one collection, but not for
> many. Here is the
> linkhttp://elegantcode.com/2009/07/19/nhibernate-2-1-and-collection-event...
>
> What happens with this implementation is that PreCollectionRemoveEvent
> executes OneShotDeleteHandler for each type defined in the
> ForChildEntities().
>
> What we need to achieve is following. We have a veryyyyyy deep object
> graph, levels upon levels, each containing 100 or more items and we
> need to delete a root item. Going through NH with regular removal from
> the collections and all-delete-orphan creates 1000's (literally) of
> delete statements, locking our whole system, and reducing system
> basically to one user system. Dead locks everywhere. To give you more
> background (and no, this is not something that I can affect, decision
> has been made before), every delete triggers a possibly more triggers
> etc, to keep old and new db in synch. Everything goes through views
> (inserts,updates, deletes) and so on and so on....
>
> I tried implementing delete listener, gathering all ids and entity
> types that I need to delete, and basically executing about 12-15
> deletes with IN clause, but I cannot stop NH from generating deletes
> too, because of the all-delete-orphan, which we also need. Please
> help...
>
> On Sep 19, 8:45 am, Jason Dentler <[email protected]> wrote:
>
>
>
> > I don't know what that is either, but I assume you're getting a concurrency
> > exception (StaleState or something like that - I forget).
>
> > Executable HQL doesn't affect anything in memory. Period. I guess you'll
> > need to evict those affected items from the session.
>
> > On Fri, Sep 17, 2010 at 2:37 PM, Fabio Maulo <[email protected]> wrote:
> > > What is OneShotDeleteHandler ?
>
> > > On Fri, Sep 17, 2010 at 11:46 AM, epitka <[email protected]> wrote:
>
> > >> Anybody knows how to suppress NH from issuing deletes of the entities
> > >> that I already deleted using HQL delete query in OneShotDeleteHandler?
>
> > >> --
> > >> You received this message because you are subscribed to the Google Groups
> > >> "nhusers" group.
> > >> To post to this group, send email to [email protected].
> > >> To unsubscribe from this group, send email to
> > >> [email protected]<nhusers%[email protected]
> > >> >
> > >> .
> > >> For more options, visit this group at
> > >>http://groups.google.com/group/nhusers?hl=en.
>
> > > --
> > > Fabio Maulo
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > > "nhusers" group.
> > > To post to this group, send email to [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected]<nhusers%[email protected]
> > > >
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/nhusers?hl=en.
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.