我遇到了NHibernate的间歇性问题,该问题会为实体生成查询,但是用来自完全不同(且不相关)的实体的列替换了其中的一列。
它只能替换单个列,通常可以通过重新启动应用程序来解决(尽管有时需要进行几次尝试)。
任何输入对此将不胜感激!
实体
public class LiquiditySourceItem : RunDataEntity, IEntity<int>
{
public virtual int Id { get; protected internal set; }
public virtual int IdentID { get; protected internal set; }
public virtual string Portfolio { get; protected internal set; }
public virtual string ProfitCentre { get; protected internal set; }
public virtual DateTime? MaturityDate { get; protected internal set; }
public virtual string Curr1 { get; protected internal set; }
public virtual string Curr2 { get; protected internal set; }
public virtual decimal Reval { get; protected internal set; }
public virtual string ContractType { get; protected internal set; }
public virtual string ContractType2 { get; protected internal set; }
public virtual string ContractCode { get; protected internal set; }
public virtual decimal AmountSignedTradeUnit { get; protected internal set; }
public virtual decimal Amount2Signed { get; protected internal set; }
public virtual decimal SpotDelta { get; protected internal set; }
public virtual string TradeRevalCurr { get; protected internal set; }
}
实体映射
public LiquiditySourceItemMap()
{
Id(x => x.Id, map => map.Column("RowId"));
Property(x => x.IdentID, map => map.Column("IdentID"));
Property(x => x.Portfolio, map => map.Column("Portfolio"));
Property(x => x.ProfitCentre, map => map.Column("ProfitCentre"));
Property(x => x.MaturityDate, map => map.Column("Con_Expiry"));
Property(x => x.BuySell, map => map.Column("BS"));
Property(x => x.Curr1, map => map.Column("Curr1"));
Property(x => x.Curr2, map => map.Column("Curr2"));
Property(x => x.Reval, map => map.Column("Reval"));
Property(x => x.ContractType, map => map.Column("ContractType"));
Property(x => x.ContractType2, map => map.Column("ContractType2"));
Property(x => x.ContractCode, map => map.Column("ContractCode"));
Property(x => x.AmountSignedTradeUnit, map => map.Column("AmountSignedTradeUnit"));
Property(x => x.Amount2Signed, map => map.Column("Amount2Signed"));
Property(x => x.ValSpot, map => map.Column("Val_Spot"));
Property(x => x.SpotDelta, map => map.Column("SpotDelta"));
Property(x => x.TradeRevalCurr, map => map.Column("Traderevalcurr"));
Property(x => x.SourceReport, map => map.Column("SourceReport"));
ManyToOne(x => x.RunContext, map => map.Column("RunContextID"));
Table("Staging.vw_Liquidity");
}
报告实体
public class BusinessBreakdownStandardPosition : ReportRunDataEntity, IEntity<long>
{
public virtual long Id { get; set; }
public virtual decimal FinalNettingAmountUSD { get; set; }
public virtual decimal InitialChargeAmountUSD { get; set; }
public virtual BusinessBreakdownInitialPrr InitialPrr { get; set; }
public virtual IEnumerable<FinalInstrumentPosition> FinalInstrumentPositions { get; set; }
public virtual decimal CreditEventPaymentUSD { get; set; }
public virtual decimal ValuationChangeIncreaseUSD { get; set; }
public virtual decimal ValuationChangeDecreaseUSD { get; set; }
public virtual string ReportKey { get; set; }
public virtual decimal USDCharge { get; set; }
public virtual decimal USDChargeICG { get; set; }
public virtual string InstrumentType { get; set; }
}
报告实体映射
public class BusinessBreakdownStandardPositionMap : ClassMapping<BusinessBreakdownStandardPosition>
{
public BusinessBreakdownStandardPositionMap()
{
Id(x => x.Id,
m =>
{
m.Column("BusinessBreakdownStandardPositionID");
m.Generator(Generators.HighLow,
g =>
g.Params(
new
{
table = "dbo.HiValue",
max_lo = 10000,
Where = string.Format("EntityName = 'BusinessBreakdownStandardPosition'")
}));
});
Property(x => x.FinalNettingAmountUSD, map => map.Column("FinalNettingAmountUSD"));
Property(x => x.InitialChargeAmountUSD, map => map.Column("InitialAmountUSD"));
Property(x => x.CreditEventPaymentUSD);
Property(x => x.ValuationChangeDecreaseUSD);
Property(x => x.ValuationChangeIncreaseUSD);
Property(x => x.USDCharge);
Property(x => x.USDChargeICG);
Property(x=>x.InstrumentType);
ManyToOne(p => p.RunContext, map => map.Column("ReportRunContextID"));
ManyToOne(p => p.InitialPrr, m =>
{
m.Column("InitialPrrID");
m.Cascade(Cascade.All);
});
Property(x => x.ReportKey);
Bag(x => x.FinalInstrumentPositions, collectionMapping =>
{
collectionMapping.Table("Reporting.BusinessBreakdownFinalInstrumentPositionStandardPositionMap");
collectionMapping.Cascade(Cascade.All);
collectionMapping.Key(k => k.Column("StandardPositionID"));
}, mapping => mapping.ManyToMany(y => y.Column("FinalInstrumentPositionID")));
Table("Reporting.BusinessBreakdownStandardPosition");
}
}
NHibernate生成的SQL查询
SELECT
this_.RowId AS RowId47_0_,
this_.IdentID AS IdentID47_0_,
this_.Portfolio AS Portfolio47_0_,
this_.ProfitCentre AS ProfitCe4_47_0_,
this_.Con_Expiry AS Con5_47_0_,
this_.BS AS BS47_0_,
this_.Curr1 AS Curr7_47_0_,
this_.Curr2 AS Curr8_47_0_,
this_.Reval AS Reval47_0_,
this_.ContractType AS Contrac10_47_0_,
this_.ContractType2 AS Contrac11_47_0_,
this_.ContractCode AS Contrac12_47_0_,
this_.AmountSignedTradeUnit AS AmountS13_47_0_,
this_.Amount2Signed AS Amount14_47_0_,
this_.Val_Spot AS Val15_47_0_,
this_.SpotDelta AS SpotDelta47_0_,
this_.InitialAmountUSD AS Initial17_47_0_,
this_.RunContextID AS RunCont18_47_0_,
this_.SourceReport AS Sou19_47_0_
FROM Staging.vw_Liquidity this_
例外
System.Data.SqlClient.SqlException (0x80131904): Invalid column name 'InitialAmountUSD'.
如您所见,nhibernate已将LiquiditySourceItem列’Traderevalcurr’替换为’InitialAmountUSD’,该列属于BusinessBreakdownStandardPosition实体。这些实体没有任何关系。否则,SQL完全符合您的期望(包括列顺序)。
观察结果
有什么想法吗?
我在NHibernate用户Google网上论坛上问了同样的问题,有人认为他们已经找到了根本原因(并且还提出了解决方案):
https://groups.google.com/forum/#!topic/nhusers/BZoBoyWQEvs
问题代码在PropertyPath.Equals(PropertyPath)中,该属性试图仅通过使用哈希码来确定相等性。这对于较小的代码库来说效果很好,因为默认的Object.GetHashCode()返回一个顺序的对象索引。但是,在垃圾回收之后,这些索引会在删除最终对象并创建新对象时重新使用…这导致多个对象获得相同的哈希码…一旦启动垃圾回收,属性路径就有机会共享相同的哈希码,这意味着它们最终将为冲突的属性混合其定制器,从而导致错误的列名…
如果要解决此错误,可以修补NH源代码:
如果您拥有自己的NH源副本,则可以通过将NHibernate / Mapping / ByCode /
PropertyPath.cs第66行从以下位置更改来修复该错误:
return hashCode == other.GetHashCode();
到:
return hashCode == other.GetHashCode() && ToString() == other.ToString();
请查看Google网上论坛以获取问题的完整详细信息。
问题内容: 我正在尝试在NHibernate中编写查询。我不在乎是否使用Criteria API或HQL,只是无法弄清楚如何编写查询。 这是我的模型: 我希望查询返回所有包含注释的工作流,该注释在注释的内容中包含特定的单词。 在伪SQL中,我将这样写: 问题答案: 我不确定Criteria API,但即使搜索仅存在于特定子类中的属性,HQL似乎也能很好地处理多态查询。我希望以下工作:
问题内容: 如何使用Criteria编写以下SQL: 问题答案: 要使用NHibernate,产生如下查询: 我们必须选择: 将子选择映射为实体。 创建原始SQL查询 第一种选择是创建一些,并将其映射为一个实体。如果我们不喜欢视图(或无法创建视图),则可以使用NHibernate映射元素element的功能 : 第二种选择是关于使用NHibernate API创建本机/原始SQL: 它没有从映射中
问题内容: 我有这个 MySQL 查询 得到这个错误: 我的表架构如下: 而且我不明白错误是从哪里来的。有任何想法吗? 问题答案: 如手册中所述: 以前,逗号运算符()和都具有相同的优先级,因此join表达式被解释为。现在具有更高的优先级,因此该表达式被解释为。此更改会影响使用子句的语句,因为该子句只能引用联接操作数中的列,并且优先级的更改会更改对这些操作数的解释。 例子: 以前,由于as的隐式分
我已经使用映射查询在ElasticSearch中执行搜索,它工作得很好,如下所示。 然而,即使我添加了“terms”,我也会得到错误:TransporDeror(400,u'parsing_exception',u'[term]格式错误的查询,预期的[END_OBJECT]但找到了[FIELD_NAME]')
问题内容: 如何使用NHibernate进行此查询 我正在使用NHibernate3。 我尝试使用新的Linq提供程序来完成此操作,但未成功。只要它产生上面确切的sql查询,我就不在乎它的执行方式。我希望编写一个强类型查询,如果可能的话,不要使用魔术字符串。 我是NHibernate的新手,所以这个问题可能很简单。 这是更多信息 我将Fluent NHibernate与AutoMappings结合
我在HDP2.3上的Presto0.148上运行复杂的查询,错误出- 我能在没有问题的情况下取消简单的查询。 我必须重新启动,然后配置更新。如果我们对结果集执行了任何操作,我认为最好将查询结果集保留在内存中。因此,Presto需要大量的保留内存,1 GB的默认设置是不够的。