Datanucleus – JDO valores nulos depués de la primer consulta

Recientemente empecé a utilizar Datanucleus para simplificar la persistencia y consulta de datos. Uno de los primeros problemas que tuve fue que al realizar una consulta por segunda vez, las propiedades del objeto eran nulas. Esto se debe al ciclo de vida de los objetos en Datanucleus, el cuál aparece en el log de la siguiente manera

13:07:41,197 DEBUG [DataNucleus.Lifecycle] – Object «mx.com.apestudio.videohaus.server.model.Video@6eb5ec12» (id=»mx.com.apestudio.videohaus.server.model.Video:bb56da010129448ab28f4486d32036b9    «) has a lifecycle change : «P_CLEAN»->»HOLLOW»

al cambiar del estado P_CLEAN a HOLLOW todas las propiedades, excepto la llave primaria, son reestablecidas a un valor nulo. Para evitar que esto suceda, podemos establecer la propiedad RetainValues a true en el archivo de configuración datanucleus.properties

datanucleus.RetainValues=true

al hacer esto, el log muestra lo siguiente

14:05:37,400 DEBUG [DataNucleus.Lifecycle] – Object «mx.com.apestudio.videohaus.server.model.Video@795cd696» (id=»mx.com.apestudio.videohaus.server.model.Video:bb56da010129448ab28f4486d32036b9    «) has a lifecycle change : «P_CLEAN»->»P_NONTRANS»

ahora el objeto pasó de un estado P_CLEAN a P_NONTRANS y conservó todas las propiedades con los valores obtenidos al realizar la primer consulta. Este modo es conveniente si sólo vas a realizar operaciones de lectura.

La otra opción es establecer la propiedad DetachAllOnCommit que, aunque es un poco mas costosa en cuanto a rendimiento, hace un ‘detach’ y ‘re-attach’ automático de los objetos. Esto es especialmente útil si vamos a actualizar alguna propiedad del objeto y queremos persistir los cambios.

datanucleus.DetachAllOnCommit=true

estas propiedades también podemos establecerlas mediante los métodos correspondientes del objeto PersistenceManager.

Cabe destacar que el problema de los valores nulos se presenta sólo cuando queremos leer propiedades del objeto fuera del contexto de una transacción.

Fuentes:
http://stackoverflow.com/questions/4630142/datanucleus-jdo-setting-fields-to-null
http://www.datanucleus.org/products/datanucleus/jdo/object_lifecycle.html
http://www.datanucleus.org/products/datanucleus/persistence_properties.html#RetainValues  
http://www.datanucleus.org/products/accessplatform_3_1/jdo/performance_tuning.html#Reading_persistent_objects_outside_a_transaction_and_PersistenceManager 

La instancia de algun proceso BPEL no aparece en la consola

En el trabajo hay un proceso de BPEL que trae algunos documentos mediante un servicio web y luego los inserta en una base de datos. Algunas ocasiones -especialmente cuando eran muchos documentos o archivos de gran tamaño- el proceso nunca aparecía en la consola despues de ser invocado. Yo esperaba que si no se insertaban los datos porque habia sucedido algun error con el servicio, al menos podria ver el flujo del proceso para saber donde ocurrió el error y tratar de resolverlo. Pero simplemente no aparecían en el listado de instancias, ni marcados como erroneos y mucho menos como ejecutados correctamente.
Donde si aparecían es en la pestaña «Administration» y luego en «Recover(Invokes)», pero no se registra el flujo del proceso ni nada.

Investigando un poco encontré que probablemente esto se debía a que ocurría un timeout en el proceso, ocasionado seguramente por la cantidad de documentos y el tamaño de los archivos. Para resolverlo hay que modificar la configuración del tiempo de expiración de las transacciones(transaction-timeout) y el tiempo de espera maximo para la respuesta de algun servicio(syncMaxWaitTime). Esto se explica claramente en el primer enlace en la parte de abajo, de todos modos dejo aqui la forma de hacerlo:

  1. Establecer las propiedades transaction-timeout y syncMaxWaitTime de la siguiente forma:

    Propiedad Ubicación El valor debe ser… Ejemplo
    transaction-timeout SOA_Oracle_Home\j2ee\home\config\transaction-manager.xml Mayor que el valor de transaction-timeout en orion-ejb-jar.xml y el valor de syncMaxWaitTime. 7200
    transaction-timeout SOA_Oracle_Home\j2ee\home\application-deployments\orabpel\ejb_ob_engine\orion-ejb-jar.xml Menor que el valor de transaction-timeout en transaction-manager.xml.

    Nota: Debes cambiar el valor de la propiedad transaction-timeout en todos los lugares donde aparece en este archivo.

    3600
    syncMaxWaitTime SOA_Oracle_Home\bpel\domains\domain_name\config\domain.xml

    donde domain_name es el nombre del dominio en el que reside el proceso.

    Menor que el valor de transaction-timeout en orion-ejb-jar.xml. 240

    Recuerda que tienes que reiniciar el servidor del SOA despues de modificar los archivos para que los cambios surtan efecto. En mi caso los valores que estableci fueron 7200, 3600 y 1200 en el orden en el que aparecen en la tabla. Despues de esto los procesos se han estado ejecutando correctamente y aparecen en la consola en el listado de instancias.

Fuentes:
Oracle® BPEL Process Manager Developer’s Guide 10g (10.1.3.1.0)
Oracle SOA Stuff
ShanBPEL