Sto utilizzando NH in un progetto che si appoggia su DB
Oracle e mi sono imbattuto in una piccola grana. Due premesse:
- Il DB è legacy, non posso modificarne in alcun modo lo schema, che non
prevede colonne di tipo timestamp da sfruttare per la concorrenza
ottimistica
- 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