0

我面臨很奇怪的問題重新NHibernate,現在它變得很頭疼。NHibernate花費較長的時間執行簡單的查詢

NHibernate花費比預期時間(幾毫秒)更長的時間(2-3分鐘)來執行這樣一個簡單的查詢。數據庫是Oracle,我正在使用ODP驅動程序。我已經檢查了所有必要的配置重新NHibernate和春天看起來對我好。當我在sqldeveloper中執行相同的查詢時,它以毫秒爲單位給出結果。

FYI - 當我使用相同的NHibernate配置執行另一個具有三個具有複雜模型的內部聯接的查詢時,我得到了預期的結果。

在調試日誌,我可以看到下面的地方是在浪費時間線:

2012-08-17 09:53:20,754 [TestRunnerThread] DEBUG - NHibernate.Connection.DriverConnectionProvider - Obtaining IDbConnection from Driver 
2012-08-17 09:55:09,369 [TestRunnerThread] DEBUG - NHibernate.AdoNet.AbstractBatcher - ExecuteReader took 108720 ms 

NHibernate的屬性設置:

<nhibernatePropertiesSettings> 
<setting name="nhibernate.connection.provider" serializeAs="String"> 
<value>NHibernate.Connection.DriverConnectionProvider</value> 
</setting> 
<setting name="nhibernate.connection.driver.class" serializeAs="String"> 
<value>NHibernate.Driver.OracleDataClientDriver</value> 
</setting> 
<setting name="nhibernate.dialect" serializeAs="String"> 
<value>NHibernate.Dialect.Oracle10gDialect</value> 
</setting> 
<setting name="nhibernate.show.sql" serializeAs="String"> 
<value>true</value> 
</setting> 
<setting name="nhibernate.query.substitutions" serializeAs="String"> 
<value>true 1, false 0, yes 'Y', no 'N'</value> 
</setting> 
<setting name="nhibernate.use.proxy.validator" serializeAs="String"> 
<value>false</value> 
</setting> 
<setting name="nhibernate.template.flush.mode" serializeAs="String"> 
<value>Never</value> 
</setting> 
</nhibernatePropertiesSettings> 

春屬性設置:

<springPropertiesSettings> 
<setting name="spring.db.provider" serializeAs="String"> 
    <value>OracleODP-11-2.0</value> 
</setting> 
</springPropertiesSettings> 

映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class name="XYZ.PaymentInvestigation.Service.Model.PaymentMessageHistory, PaymentInvestigation.Service.Model" table="MESSAGE_HIST_T" lazy="false">  
    <composite-id name="PaymentMessageHistoryId" class="XYZ.PaymentInvestigation.Service.Model.PaymentMessageHistoryId, PaymentInvestigation.Service.Model" unsaved-value="undefined"> 
     <key-property name="TransactionDate" column="TRN_DATE" /> 
     <key-property name="TransactionReferenceNumber" column="TRN_NUMBER" /> 
     <key-property name="TransactionTimeStamp" column="TRN_TIMESTAMP" /> 
     <key-property name="HistoryNumber" type="AnsiString" column="HIST_NO" /> 
     <key-property name="SubHistoryNumber" type="AnsiString" column="SUB_HIST_NO" /> 
    </composite-id> 
    <property name="EntryType" column="ENTRY_TYPE" update="false" insert="false" /> 
    <property name="Location" column="LOC" update="false" insert="false" /> 
    <property name="QueLineId" column="QUE_LINE_ID" update="false" insert="false" /> 
    <property name="DateTime" column="DATE_TIME" update="false" insert="false" /> 
    <property name="SequenceNo" column="SEQUENCE_NO" update="false" insert="false" /> 
    <property name="OperatorInitials" column="OPR_INITIALS" update="false" insert="false" /> 
    <property name="Amount" column="AMOUNT" update="false" insert="false" /> 
    <property name="MsgInfo" column="MSG_INFO" update="false" insert="false" /> 
    <property name="RecordExpired" column="RECORD_EXPIRED" update="false" insert="false" /> 
    <property name="RecordUpdated" column="RECORD_UPDATED" update="false" insert="false" /> 
    <property name="Details" column="DETAILS" update="false" insert="false" /> 
</class> 

查詢:

IList<PaymentMessageHistory> paymentMessageHistories = 
    HibernateTemplate.ExecuteFind(session => session 
     .QueryOver<PaymentMessageHistory>() 
     .Where(x => 
      x.PaymentMessageHistoryId.TransactionDate == paymentMessageId.TransactionDate && 
      x.PaymentMessageHistoryId.TransactionReferenceNumber == paymentMessageId.TransactionReferenceNumber) 
     .List()); 

PaymentMessageHistoryId型號:

public class PaymentMessageHistoryId : IEquatable<PaymentMessageHistoryId> 
{ 
    public virtual DateTime TransactionDate { get; set; } 
    public virtual int TransactionReferenceNumber { get; set; } 
    public virtual double TransactionTimeStamp { get; set; } 
    public virtual string HistoryNumber { get; set; } 
    public virtual string SubHistoryNumber { get; set; } 

    public bool Equals(PaymentMessageHistoryId other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return other.TransactionDate.Equals(TransactionDate) && other.TransactionReferenceNumber == TransactionReferenceNumber && other.TransactionTimeStamp.Equals(TransactionTimeStamp) && Equals(other.HistoryNumber, HistoryNumber) && Equals(other.SubHistoryNumber, SubHistoryNumber); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != typeof (PaymentMessageHistoryId)) return false; 
     return Equals((PaymentMessageHistoryId) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int result = TransactionDate.GetHashCode(); 
      result = (result*397)^TransactionReferenceNumber; 
      result = (result*397)^TransactionTimeStamp.GetHashCode(); 
      result = (result*397)^(HistoryNumber != null ? HistoryNumber.GetHashCode() : 0); 
      result = (result*397)^(SubHistoryNumber != null ? SubHistoryNumber.GetHashCode() : 0); 
      return result; 
     } 
    } 

    public static bool operator ==(PaymentMessageHistoryId left, PaymentMessageHistoryId right) 
    { 
     return Equals(left, right); 
    } 

    public static bool operator !=(PaymentMessageHistoryId left, PaymentMessageHistoryId right) 
    { 
     return !Equals(left, right); 
    } 

    public override string ToString() 
    { 
     return string.Format("TransactionDate: {0}, TransactionReferenceNumber: {1}, TransactionTimeStamp: {2}, HistoryNumber: {3}, SubHistoryNumber: {4}", TransactionDate, TransactionReferenceNumber, TransactionTimeStamp, HistoryNumber, SubHistoryNumber); 
    } 

PaymentMessageHistory型號:

public class PaymentMessageHistory : IEquatable<PaymentMessageHistory> 
{ 
    public virtual PaymentMessageHistoryId PaymentMessageHistoryId { get; set; } 
    public virtual string EntryType { get; set; } 
    public virtual string Location { get; set; } 
    public virtual string QueLineId { get; set; } 
    public virtual string DateTime { get; set; } 
    public virtual string SequenceNo { get; set; } 
    public virtual string OperatorInitials { get; set; } 
    public virtual decimal Amount { get; set; } 
    public virtual string MsgInfo { get; set; } 
    public virtual double RecordExpired { get; set; } 
    public virtual string RecordUpdated { get; set; } 
    public virtual string Details { get; set; } 

    public bool Equals(PaymentMessageHistory other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return Equals(other.PaymentMessageHistoryId, PaymentMessageHistoryId) && Equals(other.EntryType, EntryType) && Equals(other.Location, Location) && Equals(other.QueLineId, QueLineId) && Equals(other.DateTime, DateTime) && Equals(other.SequenceNo, SequenceNo) && Equals(other.OperatorInitials, OperatorInitials) && other.Amount == Amount && Equals(other.MsgInfo, MsgInfo) && other.RecordExpired.Equals(RecordExpired) && Equals(other.RecordUpdated, RecordUpdated) && Equals(other.Details, Details); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != typeof (PaymentMessageHistory)) return false; 
     return Equals((PaymentMessageHistory) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int result = (PaymentMessageHistoryId != null ? PaymentMessageHistoryId.GetHashCode() : 0); 
      result = (result*397)^(EntryType != null ? EntryType.GetHashCode() : 0); 
      result = (result*397)^(Location != null ? Location.GetHashCode() : 0); 
      result = (result*397)^(QueLineId != null ? QueLineId.GetHashCode() : 0); 
      result = (result*397)^(DateTime != null ? DateTime.GetHashCode() : 0); 
      result = (result*397)^(SequenceNo != null ? SequenceNo.GetHashCode() : 0); 
      result = (result*397)^(OperatorInitials != null ? OperatorInitials.GetHashCode() : 0); 
      result = (result*397)^Amount.GetHashCode(); 
      result = (result*397)^(MsgInfo != null ? MsgInfo.GetHashCode() : 0); 
      result = (result*397)^RecordExpired.GetHashCode(); 
      result = (result*397)^(RecordUpdated != null ? RecordUpdated.GetHashCode() : 0); 
      result = (result*397)^(Details != null ? Details.GetHashCode() : 0); 
      return result; 
     } 
    } 

    public static bool operator ==(PaymentMessageHistory left, PaymentMessageHistory right) 
    { 
     return Equals(left, right); 
    } 

    public static bool operator !=(PaymentMessageHistory left, PaymentMessageHistory right) 
    { 
     return !Equals(left, right); 
    } 

    public override string ToString() 
    { 
     return string.Format("PaymentMessageHistoryId: {0}, EntryType: {1}, Location: {2}, QueLineId: {3}, DateTime: {4}, SequenceNo: {5}, OperatorInitials: {6}, Amount: {7}, MsgInfo: {8}, RecordExpired: {9}, RecordUpdated: {10}, Details: {11}", PaymentMessageHistoryId, EntryType, Location, QueLineId, DateTime, SequenceNo, OperatorInitials, Amount, MsgInfo, RecordExpired, RecordUpdated, Details); 
    } 

我經歷了這個NHibernate taking a long time to run query但沒有爲我工作。

請幫忙!

問候, Milind

+0

我的最新發現:當我刪除x.PaymentMessageHistoryId.TransactionDate == paymentMessageId.TransactionDate條件,那麼它工作正常。意味着與數據類型有關。 – Milind 2012-08-17 02:25:51

回答

0

一個更簡單的解決方案不是繼承Oracle驅動程序類是隻添加一個類型屬性,在財產和價值將是「日期」。這是NHibernate類型。

<key-property name="TransactionDate" type="Date" column="TRN_DATE" /> 
0
public class OracleDataClientDriver2 : OracleDataClientDriver 
{ 
    protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType) 
    { 
     switch (sqlType.DbType) 
     { 
      //Timestamp columns not indexed by Oracle 11g date columns. - Use Date 
      case DbType.DateTime: 
       base.InitializeParameter(dbParam, name, SqlTypeFactory.Date); 
       break; 
      default: 
       base.InitializeParameter(dbParam, name, sqlType); 
       break; 
     } 
    } 
} 

,改變connection.driver_class的價值= nameSpace.OracleDataClientDriver2,的AssemblyName

+0

這裏是解決方案http://stackoverflow.com/questions/7684163/problems-with-nhibernate-and-datetime-mappings – Milind 2012-08-17 04:05:28