N2CMS, NHibernate (o Hibernate), Oracle y ORA-01461 (LONG y NCLOB)

En esta entrega voy a compartir algunos problemas que tuvimos con la bendita conexión a Oracle.

Uno de ellos, fue la existencia de un Rack de servidores en el cliente, es decir, más de un servidor funcionando en paralelo. Además, tenían dos versiones del cliente de Oracle conviviendo en el servidor (cosa que no habían indicado cuando nos dieron las especificaciones técnicas del servidor y que aparecieron “oh caramba!”, cuando se hizo el primer despliegue). Uno era Oracle8i, otro Oracle10g. Nuestra aplicación “misteriosamente” se conectaba a veces si, otras veces no… Como N2CMS (en realidad Hibernate) no soporta el conector 8i, obviamente, esto ocasionaba errores, cuelgues y cosas muy muy raras 🙂

Bueno… no tanto, pero explotaba 🙂

En fin, el problema fue el siguiente: cuando en el web.config seleccionamos la conexión, elegimos “Oracle10g”, el cual, en el código fuente del N2 usaba el driver “default” de Microsoft para conectarse, y este driver, funciona mal. De hecho, el mismo Visual Studio te recomienda no usarlo :S. Conclusión, le modificamos el siguiente código:

ConfigurationBuilder.cs

case DatabaseFlavour.Oracle:
case DatabaseFlavour.Oracle10g:

Properties[NHibernate.Cfg.Environment.ConnectionDriver] = typeof(NHibernate.Driver.OracleDataClientDriver).AssemblyQualifiedName;
Properties[NHibernate.Cfg.Environment.Dialect] = typeof(NHibernate.Dialect.Oracle10gDialect).AssemblyQualifiedName;
break;

Usando OracleDataClientDriver toma el driver proporcionado por el cliente y no el default de Microsoft. Y con eso, se solucionó ese problemita.

mision cumplida

Otro problema que tuvimos fue el largo de los textos. Por algún motivo, el mapeo de los strings no estaba funcionando correctamente y los valores se convertían a un tipo de dato inválido. El error que teníamos era

ORA-01461: can bind a LONG value only for insert into a LONG column

Eso lo solucionamos modificando la siguiente linea en el código:

ConfigurationBuilder.cs

ca.Property(x => x.StringValue, cm => { cm.Type(NHibernateUtil.AnsiString); cm.Length(stringLength); });

flawless victory

Espero que les sirva, al menos para que no padezcan los mismos sobresaltos que nosotros si tienen los mismos errores.

¡Hasta la próxima!


Discussion Area - Leave a Comment