Crad's .NET Blog

L'UGIblog di Marco De Sanctis
posts - 190, comments - 457, trackbacks - 70

[NHibernate] Oracle e la concorrenza ottimistica

Sto utilizzando NH in un progetto che si appoggia su DB Oracle e mi sono imbattuto in una piccola grana. Due premesse:

  1. Il DB è legacy, non posso modificarne in alcun modo lo schema, che non prevede colonne di tipo timestamp da sfruttare per la concorrenza ottimistica
  2. Oracle, come molti sapranno, non ha il concetto di stringa vuota: al suo posto memorizza sempre NULL

Impostando l'attributo

<class ... optimistic-lock="dirty" ... >
  
...
</class>

NH, in corrispondenza di UPDATE o DELETE, crea la classica clausola WHERE con i valori originali delle proprietà. Il problema è che, se una di queste valeva string.Empty, la query inviata al DB è

UPDATE   ....
WHERE    ...
AND      
STRING_FIELD :p1

con :p1 valorizzato a DBNull.Value. Ovviamente Oracle non effettua l'update in quanto la WHERE non è corretta: si sarebbe dovuto avere

UPDATE   ....
WHERE    ...
AND      
STRING_FIELD IS NULL

Come risolvere in maniera "trasparente", cioé senza essere costretti a modificare tutte le proprietà di tipo string delle entity di dominio per far tornare null? La soluzione è possibile grazie ad un Interceptor, che operi nel modo seguente:

public override bool OnFlushDirty( ... )
{
    
// questo serve a fixare il bug sulle stringhe vuote nella WHERE
    
if (previousState != null)
    {
        
for (int i = 0; i <= types.Length - 1; i++)
        {
            
if (types[i].ReturnedClass == typeof(string) &&
                (
string)previousState[i] == string.Empty)
            {
                res = 
true;
                previousState[i] = 
null;
            }
        }
    }
    
return res;
}

In questo modo, impostando a null tutte le stringhe vuote che troviamo nei valori original, NH riesce a creare una clausola WHERE corretta. Ovviamente lo stesso va fatto anche nel metodo OnDelete.

HTH

powered by IMHO 1.3

Print | posted on giovedì 7 settembre 2006 12:03 | Filed Under [ NHibernate ]

Powered by:
Powered By Subtext Powered By ASP.NET