2009-03-02 4 views
17

Ho un database precedente che sto mappando utilizzando NHibernate. Gli oggetti di interesse sono un account e un elenco di oggetti di notifica. Gli oggetti assomigliano:Caricamento lento non funzionante per la relazione molti a uno durante l'associazione a un campo non chiave utilizzando la proprietà ref

public class Notification 
{ 
    public virtual int Id { get; set; } 
    public virtual DateTime BatchDate { get; set; } 
    /* other properties */ 

    public virtual Account Account { get; set; } 
} 

public class Account 
{ 
    public virtual int Id { get; set; } 
    public virtual string AccountNumber { get; set; } 
    /* other properties */ 
} 

I file di mapping simile:

<class name="Account" table="Account" dynamic-update="true"> 
<id name="Id" column="AccountID"> 
    <generator class="native" /> 
</id> 
<property name="AccountNumber" length="15" not-null="true" /> 
    <!-- other properties --> 
</class> 

<class name="Notification" table="Notification"> 
    <id name="Id" column="Id"> 
     <generator class="native" /> 
    </id> 
    <!-- other properties --> 
    <many-to-one name="Account" class="Account" property-ref="AccountNumber" lazy="proxy"> 
     <column name="AcctNum" /> 
    </many-to-one> 

Tuttavia, quando creo un criterio come

return session.CreateCriteria(typeof(Notification)).List<Notification>(); 

sto ottenendo un caso Select N + 1 in cui ogni account viene caricato anche se l'account non viene mai referenziato. Perché tutti gli account vengono caricati quando il numero uno è mappato come proxy pigro?

+0

ottengo lo stesso problema, mi ricordo di aver visto un post somehwere dire molti-a-uno di proprietà Ref non può essere caricato in modo pigro , Non riesco a trovare la fonte. Questo era con NH 1.2 – Jafin

risposta

13

Il problema è causato dall'attributo property-ref. Il caricamento lento funziona solo quando il riferimento many-to-one utilizza la chiave primaria dell'altro oggetto poiché NHibernate presuppone che ci sia un vincolo di chiave esterna che impone la validità di tale valore. Con una chiave non primaria (indicata dalla proprietà ref), NHibernate non fa questa ipotesi e quindi non si assume che l'oggetto correlato debba esistere. Poiché non desidera creare un proxy per un oggetto che non esiste (vale a dire dovrebbe essere nullo invece di un proxy), recupera avidamente l'oggetto remoto. Questo stesso problema si verifica quando viene specificato not-found="ignore" poiché ciò indica che la relazione di chiave esterna non viene applicata e può determinare un riferimento null.

Consulta anche:

+0

Il problema in NH sembra essere in TwoPhaseLoad.cs - ispeziona LoadedState e chiama IType.ResolveIdentifier per tradurre i KEY in Entità o Proxy. L'IType qui coinvolto è ManyToOne (PK = false, Uniq = true, eager = false). Finisce per chiamare ResolveIdentifier (valore, sessione, proprietario) dalla base EntityType.cs, e quello controlla IsReferenceToPrimaryKey (= false) e chiama LoadByUniqueKey(). Questo a sua volta ha un commento interessante "TODO: implementare il caching? Proxy?" (SÌÌ). Quindi, combo di session.PersistenceContext.GetEntity (new EntityUniqueKey (.. key)) + persister.LoadByUniqueKey (.. key) recupera l'entità. – quetzalcoatl

Problemi correlati