2013-06-07 4 views
18

हमें NHibernate के साथ एक अंतःविषय समस्या है जहां यह कभी-कभी SQL पर गलत कॉलम के साथ एक क्वेरी उत्पन्न करेगा। अगर हम एप्लिकेशन को पुनरारंभ करते हैं तो समस्या घट जाती है (कभी-कभी इसे एक से अधिक पुनरारंभ करने की आवश्यकता होती है)। जब समस्या होती है, उस प्रक्रिया के जीवनकाल के दौरान, यह हमेशा प्रभावित इकाई के लिए गलत SQL उत्पन्न करता है। यह हमेशा एक ही प्रभावित इकाई नहीं है।क्वेरीज़ पर गलत कॉलम उत्पन्न करना

यह एक एएसपी.NET एप्लिकेशन है जहां sessionFactory एप्लिकेशन_स्टार्ट ईवेंट के दौरान बनाया गया है। सभी विन्यास और मैपिंग कोड द्वारा किया जाता है।

हमारे पास एप्लिकेशन का परीक्षण या डिबग करने का कोई और विचार नहीं है, और मुझे लगता है कि एनएचबीरनेट में कुछ बग है, क्योंकि एप्लिकेशन पुन: प्रारंभ होने पर स्वयं को ठीक करता है। किसी भी विचार/सुझावों की बहुत सराहना की जाएगी!

Here's एक उदाहरण:

इकाई

namespace Example.Clinicas 
{ 
    public partial class Clinica : Entidade // Abstract base class that has a property Handle 
    { 
     public virtual string Ddd { get; set; } 
     public virtual string Ddd2 { get; set; } 
     public virtual long? Duracao { get; set; } 
     public virtual string Numero { get; set; } 
     public virtual string Numero2 { get; set; } 
     public virtual string Prefixo { get; set; } 
     public virtual string Prefixo2 { get; set; } 
     public virtual long? HandlePrestador { get; set; } 
     public virtual Example.Prestadores.Prestador Prestador { get; set; } 
    } 
} 

मानचित्रण

namespace Example.Clinicas.Mappings 
{ 
    public class ClinicaMapping : ClassMapping<Clinica> 
    { 
     public ClinicaMapping() 
     { 
      Table("CLI_CLINICA"); 

      Id(x => x.Handle, map => 
      { 
       map.Column("HANDLE"); 
       map.Generator(Generators.Sequence, g => g.Params(new { sequence = "SEQ_AUTO1816" })); 
      }); 
      Property(x => x.Ddd, map => map.Column(c=> 
      { 
       c.Name("DDD1"); 
       c.Length(4); 
      })); 
      Property(x => x.Ddd2, map => map.Column(c=> 
      { 
       c.Name("DDD2"); 
       c.Length(4); 
      })); 
      Property(x => x.Duracao, map => map.Column("INTERVALOAGENDA")); 
      Property(x => x.Numero, map => map.Column(c=> 
      { 
       c.Name("NUMERO1"); 
       c.Length(5); 
      })); 
      Property(x => x.Numero2, map => map.Column(c=> 
      { 
       c.Name("NUMERO2"); 
       c.Length(5); 
      })); 
      Property(x => x.Prefixo, map => map.Column(c=> 
      { 
       c.Name("PREFIXO1"); 
       c.Length(5); 
      })); 
      Property(x => x.Prefixo2, map => map.Column(c=> 
      { 
       c.Name("PREFIXO2"); 
       c.Length(5); 
      })); 
      Property(x => x.HandlePrestador, map => map.Column("PRESTADOR")); 
      ManyToOne(x => x.Prestador, map => 
      { 
       map.Column("PRESTADOR"); 
       map.Insert(false); 
       map.Update(false); 
      }); 
     } 
    } 
} 

कमान

Session.Query<Clinica>().FirstOrDefault(); 

जेनरेट किए गए एसक्यूएल

select HANDLE489_, 
     DDD2_489_, 
     DDD3_489_, 
     INTERVAL4_489_, 
     NUMERO5_489_, 
     NUMERO6_489_, 
     PREFIXO7_489_, 
     FATURADE8_489_, 
     PRESTADOR489_ 
    from (select clinica0_.HANDLE    as HANDLE489_, 
       clinica0_.DDD1     as DDD2_489_, 
       clinica0_.DDD2     as DDD3_489_, 
       clinica0_.INTERVALOAGENDA  as INTERVAL4_489_, 
       clinica0_.NUMERO1    as NUMERO5_489_, 
       clinica0_.NUMERO2    as NUMERO6_489_, 
       clinica0_.PREFIXO1    as PREFIXO7_489_, 
       clinica0_.FATURADEPARCELAMENTO as FATURADE8_489_, 
       clinica0_.PRESTADOR   as PRESTADOR489_ 
      from CLI_CLINICA clinica0_) 
where rownum <= 1 

अपवाद

ORA-00904: "CLINICA0_"."FATURADEPARCELAMENTO": invalid identifier 

दिलचस्प टिप्पणियों:

  • यह अधिक बड़ा entit प्रभावित होने की संभावना है ies (जिसमें गुणों की एक बड़ी संख्या है), लेकिन कभी-कभी छोटी इकाइयों को भी प्रभावित करती है;
  • जेनरेट किए गए एसक्यूएल में मैप किए गए गुणों के समान कॉलम की संख्या समान होती है;
  • एसक्यूएल पर कॉलम मैपिंग क्लास पर मैप किए गए गुणों के समान क्रम में हैं;
  • गलत कॉलम मौजूदा को प्रतिस्थापित करेगा;
  • गलत कॉलम एक अलग मैप किए गए इकाई में एक मान्य कॉलम है;
  • प्रभावित इकाई और गलत कॉलम वाले किसी के बीच कोई संबंध नहीं है;

अन्य विवरण:

  • नेट संस्करण: 4,0
  • NHibernate संस्करण: NHibernate.Mapping: कोड द्वारा 3.3.3.400
  • मानचित्रण।ByCode कोड द्वारा
  • विन्यास: NHibernate.Cfg

लोड मैपिंग

var mapper = new ModelMapper(); 

foreach (var assembly in resolver.GetAssemblies()) // resolver is a class that gets all the assemblies for the current application 
    mapper.AddMappings(assembly.GetExportedTypes()); 

var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities(); 

return mapping; 

SessionFactory विन्यास

var configure = new Configuration(); 
configure.DataBaseIntegration(x => 
            { 
             x.Dialect<Oracle10gDialect>(); // Custom class 
             x.ConnectionString = ConnectionString; 
             x.BatchSize = 100; 
             x.Driver<OracleMultiQueryDataClientDriver>(); // Custom class 
             x.MaximumDepthOfOuterJoinFetching = 10; 
             x.Timeout = 250; 
             x.PrepareCommands = true; 
             x.HqlToSqlSubstitutions = "true 'S', false 'N', yes 'S', no 'N'"; 
             x.LogFormattedSql = true; 
             x.LogSqlInConsole = true; 
             x.AutoCommentSql = true; 
             x.IsolationLevel = IsolationLevel.ReadCommitted; 
             x.ConnectionProvider<ConnectionProvider>(); // Custom class 
            }); 
configure.Properties.Add(new KeyValuePair<string, string>("hibernate.command_timeout", "250")); 
configure.Proxy(x => x.ProxyFactoryFactory<NHibernate.Bytecode.DefaultProxyFactoryFactory>()); 
configure.LinqToHqlGeneratorsRegistry<LinqToHqlGeneratorsRegistry>(); 
configure.CurrentSessionContext<NHibernate.Context.WebSessionContext>(); 
var mapping = GetMappings(); // Method showed above 
mapping.autoimport = false; 
configure.AddMapping(mapping); 
var listener = new AuditEventListener(); 
configure.EventListeners.PostInsertEventListeners = new IPostInsertEventListener[] { listener }; 
configure.EventListeners.PostUpdateEventListeners = new IPostUpdateEventListener[] { listener }; 
configure.SessionFactory().GenerateStatistics(); 
return configure; 
+0

क्या आपके पास एक ही डेटाबेस तालिका में मैप किए गए एक से अधिक इकाई हैं? – rivarolle

+0

कुछ हैं, लेकिन इस मामले में नहीं। क्लिनिका CLI_CLINICA तालिका में एकमात्र मैप की गई इकाई है। –

+0

क्या यह हमेशा एक ही अमान्य कॉलम का संदर्भ देता है? – mxmissile

उत्तर

1

अपने querylog चेक क्वेरी किस प्रकार को देखने के लिए आईटी इस Runnig, वहां से अपने एसक्यूएल में, समस्या को हल कर सकते हैं।

1

ऐसा लगता है कि "क्रेडिट कार्ड भुगतान" FATURADEPARCELAMENTO आपके "ऋणदाता" ऑब्जेक्ट PRESTADOR पर एक संपत्ति है, यदि ऐसा है तो इसे मैपिंग में एक संदर्भ और संपत्ति नहीं होना चाहिए। उम्मीद है कि आपको सही दिशा में

संदर्भ आपकी लाइन संपत्ति (x => x.HandlePrestador, map => map.Column ("PRESTADOR")) की जगह ले जाएगा। और संदर्भ (x => x.HandlePrestador) के करीब कुछ होगा

4

मैं NHibernate उपयोगकर्ता Google समूह मंच पर एक ही सवाल पूछा, और किसी सोचता है कि वे बाहर मूल कारण काम किया है (और यह भी एक प्रस्ताव किया है समाधान):

https://groups.google.com/forum/#!topic/nhusers/BZoBoyWQEvs

समस्या कोड PropertyPath.Equals (PropertyPath) जो केवल हैश कोड का उपयोग करके समानता निर्धारित करने का प्रयास कर रही है। यह छोटे ऑब्जेक्ट बेस के लिए ठीक काम करता है क्योंकि डिफ़ॉल्ट ऑब्जेक्ट। गेटहाशकोड() अनुक्रमिक ऑब्जेक्ट इंडेक्स देता है। हालांकि, कचरा संग्रह के बाद, इन सूचकांकों का पुन: उपयोग किया जाता है क्योंकि अंतिम वस्तुएं हटा दी जाती हैं और नई वस्तुएं बनाई जाती हैं ... जिसके परिणामस्वरूप एक से अधिक ऑब्जेक्ट एक ही हैशकोड प्राप्त होते हैं ... एक बार कचरा संग्रह में शामिल हो जाता है, संपत्ति पथों को साझा करने का मौका होता है एक ही hashCode वे अंततः टकराने गुण, इस प्रकार गलत स्तंभ नाम के लिए अपने कस्टमाइज़र अप मिश्रण होगा जिसका मतलब है कि ...

आप इस बग को ठीक करना चाहते हैं, तो आप राष्ट्रीय राजमार्ग स्रोत कोड पैच कर सकते हैं:

यदि आपके पास एनएच स्रोत की अपनी प्रति है, तो आप एनएचबीर्नेट/मैपिंग/बायकोड/प्रॉपर्टीपाथ.cs लाइन # 66 को बदलकर बग को ठीक कर सकते हैं:

return hashCode == other.GetHashCode();

करने के लिए:

return hashCode == other.GetHashCode() && ToString() == other.ToString();

रही समस्या के सम्पूर्ण जानकारी हेतु Google समूह देखें।

संबंधित मुद्दे