Migración

Para migrar de OpenXava 2.2.5 a OpenXava 3.0

El proveedor de persistencia por defecto es JPA

Desde la v3.0 OpenXava usa JPA por defecto para la persistencia. Si quieres seguir usando Hibernate como proveedor de persistencia en tu aplicación pon la siguiente línea en el archivo xava.properties de tu proyecto:
persistenceProviderClass=org.openxava.model.impl.HibernatePersistenceProvider

MapFacade ya no lanza RemoteException

Ahora los método de MapFacade no lanzan RemoteException sino SystemException, que es una excepción runtime.
Esto tiene poca repercusión en tu código, pero si tienes algo así:
try {
    MapFacade.validate("Factura", valores);
}
catch (RemoteException ex) {
    ...
}
Entonces tendrás que cambiar la RemoteException por una SystemException:
try {
    MapFacade.validate("Factura", valores);
}
catch (SystemException ex) {
    ...
}
Además, XavaException ahora es una excepción runtime. Pero esto no implica ningún cambio en tu código.

Para migrar de OpenXava 2.2.4 a OpenXava 2.2.5

MapFacade no es autocommit a partir de ahora

Hasta ahora, cuando escribiamos:
MapFacade.create("Cliente", valoresCliente);
MapFacade.create("Factura", valoresFactura);
Estas dos líneas eran dos transacciones. Si la creación de la factura fallaba el cliente se grababa. Es decir, MapFacade tenía una política de autocommit.
Desde ahora MapFacade no es autocommit por defecto, es decir, el caso de arriba tendrá solo una transacción, confirmada por OX al final de la acción o el test. Ahora, si la creación de la factura falla la creación del cliente no se producirá.
Esto puede alterar ligeramente el comportamiento de nuestras acciones en caso de fallo, pero solo si nuestras ascciones hacen varias llamadas a MapFacade. Si queremos preservar el comportamiento anterior tenemos dos opciones.
Primera opción: añadir la siguiente línea a nuestro archivo properties/xava.properties:
mapFacadeAutoCommit=true
Segunda opción: confirmar la acción manualmente. Por ejemplo, el código de arriba se puede escribir de esta forma:
MapFacade.create("Cliente", valoresCliente);
MapFacade.commit();
MapFacade.create("Factura", valoresFactura);
MapFacade.commit();

Para migrar de OpenXava 2.2.3 a OpenXava 2.2.4

El esquema para table de imagenes del estereotipo GALERIA_IMAGENES

Ahora el esquema para la table de imagenes se especifica separadamente, es decir,
Now the schema for image table is specified specified separately, that is, ante escribiamos esto en nuestro archivo de propiedades de configuración:
images.table=XAVATEST.IMAGES
Ahora hemos de escribir:
images.schema=XAVATEST
images.table=IMAGES

Para migrar de OpenXava 2.2.2 a OpenXava 2.2.3

Las etiquetas del modo lista y colecciones son calificadas (para las pruebas junit)

Las etiquetas pare el modo lista y las colecciones ahora son calificadas, es decir si tenemos una propiedad cliente.nombre, antes la etiqueta era Nombre, y ahora es Nombre de Cliente. Esto puede afectar nuestras pruebas junit, es decir, si tenemos:
assertLabelInList(2, "Nombre"); // de cliente.nombre
ahora tenemos que escribir:
assertLabelInList(2, "Nombre de Cliente"); de cliente.nombre

Esquema de tabla de AccessTracking cambiado

En el proyecto AccessTracking el esquema de la tabla para registrar los accesos ha cambiado:
Es necesario cambiar nuestras tabla actual si queremos actualizar a AccessTracking 2.2.3
Este cambio se ha hecho para que AccessTracking pueda funcionar en bases de datos que no soporten TABLE, DATE y TIME como nombre de columna.

Para migrar de OpenXava 2.2.1 a OpenXava 2.2.2

Sin consideraciones

Para migrar de OpenXava 2.2 a OpenXava 2.2.1

MoneyFormatter (para pruebas junit)

Un formateador de dinero es aplicado por defecto para formatear o analizar todos los valores con el estereotipo DINERO, ahora toda la información de tipo dinero es siempre visualizada usando dos cifras decimales. Por tanto, hemos de adaptar nuestras pruebas junit, cambiando líneas como esta:
assertValue("importe", "20");
por algo así:
assertValue("importe", "20.00");
O, si así lo preferimos podemos usar la vieja forma de formatear, solo hemos de desactivar el formateador o definir el nuestro propio editando nuestro archivo editores.xml.

Acción 'Mode.list" no está disponible cuando el usuario navega a otra vista (para pruebas junit)

Cuando el usuario navega a otra vista (por ejemplo para crear o modificar una referencia) el vínculo para ir al modo lista ahora no está presente. Quizás necesites cambiar tu prueba junit:
Por ejempo, en este código junit:
execute("Reference.createNew", "model=Family2,keyProperty=xava.Product2.family.number");
assertAction("Mode.list"); // Desde 2.2.1 falla
El assertAction("Mode.list") se tiene que quitar

Para migrar de OpenXava 2.1.5 a OpenXava 2.2

El comportamiento por defecto para las colecciones de entidades cambia

Ahora, cuando el usuario pulsa en 'Añadir' en una colección de entidades, va a una lista donde puede escoger varias entidades para añadir. Esto puede causar que nuestro actual código JUnit falle. Necesitamos hacer unas simples modificaciones; sencillamente cambiar código como este en nuestras pruebas JUnit:
execute("Collection.new", "viewObject=xava_view_customers");
setValue("customers.number", getCustomerNumber2());
assertValueIgnoringCase("customers.name", getCustomer2().getName());
assertCollectionRowCount("customers",0);
execute("Collection.save", "viewObject=xava_view_customers");
assertCollectionRowCount("customers",1);
por este otro:
assertCollectionRowCount("customers",0);
execute("Collection.add", "viewObject=xava_view_customers");
assertValueInList(5, 0, getCustomer2().getName());
execute("AddToCollection.add", "row=5");
assertMessage("1 element(s) added to Customers of Seller");
assertCollectionRowCount("customers",1);
Además, el usuario ahora puede añadir varias entidades a la vez, esto es, un código como este:
execute("Collection.new", "viewObject=xava_view_customers");
setValue("customers.number", getCustomerNumber1());
assertValueIgnoringCase("customers.name", getCustomer1().getName());
assertCollectionRowCount("customers", 0);
execute("Collection.save", "viewObject=xava_view_customers");
assertMessage("Customer associated to Seller");
 
assertCollectionRowCount("customers", 1);
setValue("customers.number", getCustomerNumber2());
assertValueIgnoringCase("customers.name", getCustomer2().getName());
execute("Collection.save", "viewObject=xava_view_customers");
assertCollectionRowCount("customers",2);
se puede escribir así:
execute("Collection.add", "viewObject=xava_view_customers");
assertValueInList(4, 0, getCustomer1().getName());
assertValueInList(5, 0, getCustomer2().getName());
checkRow(4);
checkRow(5);
execute("AddToCollection.add");
assertMessage("2 element(s) added to Customers of Seller");
assertCollectionRowCount("customers",2);

El comportamiento por defecto para las colecciones de agregados cambia

Ahora, cuando un detalle de una collección se graba, la vista del detalle no se oculta, esto puede causar que nuestro actual código JUnit falle. Necesitamos hacer unas simples modificaciones; sencillamente cambiar código como este en nuestras pruebas JUnit:
execute("Collection.save", "viewObject=xava_view_section1_details");
execute("Collection.new", "viewObject=xava_view_section1_details"); // A borrar
por este otro:
execute("Collection.save", "viewObject=xava_view_section1_details");
Es decir, borrar la llamada a "Collection.new", porque despues de grabar el detalle, la acción "new" se ejecuta automáticamente, así la interfaz de usuario está lista para introducir un nuevo detalle.

Para migrar de OpenXava 2.1.4 a OpenXava 2.1.5

No hay consideraciones

Para migrar de OpenXava 2.1.3 a OpenXava 2.1.4

Nuevas acciones en colecciones (para pruebas junit)

Las collecciones tienen nuevas acciones disponibles para los usuarios, por tanto si comprobamos todas las acciones presentes en nuestras pruebas junit hemos de modificar nuestras pruebas para que tengas en cuenta las nuevas acciones.
Es decir, si tenemos algo como esto en nuestro código de prueba junit:
        String [] acciones = {
            "Navigation.previous",
            "Navigation.first",
            "Navigation.next",
            "CRUD.new",
            "CRUD.save",
            "CRUD.delete",
            "CRUD.search",
            "Collection.new",
            "Collection.removeSelected"
        };
        assertActions(acciones);
hemos de cambiarlo por:
    String [] acciones = {
            "Navigation.previous",
            "Navigation.first",
            "Navigation.next",
            "CRUD.new",
            "CRUD.save",
            "CRUD.delete",
            "CRUD.search",
            "Collection.new",
            "Collection.removeSelected",
            "List.filter",        // Nuevo
            "List.orderBy",       // Nuevo
            "List.customize",     // Nuevo
            "List.hideRows",      // Nuevo
            "Print.generatePdf",  // Nuevo
            "Print.generateExcel" // Nuevo
        };
        assertActions(acciones);

Tarea Ant generarPortlets eliminada

La tarea ant generarPorltets ha sido quitada de OpenXava/build.xml porque ahora es exactamente igual que generatePortlets. Por lo tanto, si en tu build.xml tienes algo como esto:
<target name="generarPortlets">
    <ant antfile="../OpenXava/build.xml" target="generarPortlets"/>
</target>
Tienes que cambiarlo por:
<target name="generarPortlets">
    <ant antfile="../OpenXava/build.xml" target="generatePortlets"/>
</target>

Para migrar de OpenXava 2.1 a OpenXava 2.1.3

Pruebas JUnit y claves sin valor interpretadas como cero

Desde 2.13 si una propieda clave de tipo int, long o short no tiene valor en la vista cuando es interpretada, es interpretada como nulo (sin valor), y no como cero. Esto no tiene efecto en el usuario final, pero posiblemente necesitemos cambiar algunas pruebas JUnit, por ejemplo
Since 2.1.3 if a property key of type int, long or short has no value in view when it is parsed is parsed with null (without value), and not as zero. This has no effect in final user, but possibly you need to modify some junit test. Por ejemplo si tenemos una prueba así:
public void testAlgo() throws Exception {
  assertValue("codigo", "");
  execute("MiControlador.miAccion"); // Esto no cambia el valor de 'codigo'
  assertValue("codigo", "0"); // porque OX interpreta una cadena vacía como un 0 (hasta 2.1.2)
  ...
}
Ahora hemos de escribirlo así:
public void testAlgo() throws Exception {
  assertValue("codigo", "");
  execute("MiControlador.miAccion"); // Esto no cambia el valor de 'codigo'
  assertValue("codigo", ""); // porque ahora (desde 2.1.3) OX interpreta cadena vacía como nulo
  ...
}

Para migrar de OpenXava 2.0.4 a OpenXava 2.1

Proyectos WebSphere

Si despliegas tus proyectos en WebSphere necesitas hacer algunos pequeños ajustes:
Primero, en el archivo hibernate/hibernate.cfg.xml de tu proyecto añade el siguiente código marcado en azul:
<session-factory>
        <property name="hibernate.connection.datasource">@datasource.prefix@/@datasource@</property>
        <property name="hibernate.dialect">@hibernate.dialect@</property>
        <property name="hibernate.jdbc.use_get_generated_keys">false</property>
        <property name="hibernate.show_sql">false</property>
        @hibernate.properties@
        ...
</session-factory>
Segundo, en tu archivo de configuración para websphere (por ejemplo websphere-as400.properties) has de añadir:
hibernate.properties=<property name="hibernate.transaction.manager_lookup_class">\n\
\t\t\torg.hibernate.transaction.WebSphereTransactionManagerLookup\n\
\t\t</property>\n\
\t\t<property name="transaction.factory_class">\n\
\t\t\torg.hibernate.transaction.JTATransactionFactory\n\
\t\t</property>

Otros cambios que requieren migración

Para migrar de OpenXava 2.0.3 a OpenXava 2.0.4

Parse de valores numéricos

Ahora los datos de tipo Number (Integer, BigDecimal, Short, etc) y Boolean (no boolean) son interpretados como nulo si en la interfaz de usuario están en blanco. Antes los campos numérico en blanco se interpretaban como 0. Este cambio no produce grandes incompatibilidades porque default-converters This change does not produce big incompatibility problems because default-converters.xml define las conversiones reales antes de grabar en la base de datos (que es lo que de verdad importa). Es decir, este cambio afecta solo a la visualización. Tus asuntos de incompatibilidad pueden ser:

Cambios en las API

Para migrar de OpenXava 2.0.2 a OpenXava 2.0.3

No se lanzan eventos al-cambiar cuando se busca

La guía de referencía (en la sección 7.5) dice que CRUD.searchByViewKey no lanza ningún evento al-cambiar, y CRUD.searchExecutingOnChange lanza todos los eventos al-cambiar. Pero por causa de un bug en ox2.0.2 (y anteriores) CRUD.searchByViewKey lanzaba al-cambiar de las claves en las referencias, y CRUD.searchExecutingOnChange no lanzaba al-cambiar de las claves en las referencias. Este problema ha sido resuelto, por la tanto si tienes código que confía en este comportamiento erroneo deberás adaptarlo.

Establece valor para referencías (en combos) con clave múltiple en las pruebas JUnit

Establece valor para referencías (en combos) con clave múltiple en las pruebas JUnit tiene que hacerse usando POJOs, el uso de claves primarias EJB2 no está soportado.
Ver documentación en Para migrar de OpenXava 1.2.1 a OpenXava 2.0 below.

Para migrar de OpenXava 2.0.1 a OpenXava 2.0.2

La acción Collection.hiddenDetail ha sido renombrada a Collection.hideDetail en controllers.xml. Debemos renombrar la acción dentro de nuestras pruebas junit.

Para migrar de OpenXava 2.0 a OpenXava 2.0.1

No hay consideraciones

Para migrar de OpenXava 1.2.1 a OpenXava 2.0

Establece valor para referencías (en combos) con clave múltiple en las pruebas JUnit

Hasta ahora, para establecer valor a una referencía visualizada como lista-descripciones (como combo), y mapeada a la base de datos usando varias columnas, escribiamos:
PermisoConduccionKey clave = new PermisoConduccionKey();
clave.setType("C ");
clave.setLevel(1);
setValue("drivingLicence.KEY", clave.toString());
Pero, si usamos solo POJOs, sin clases 'Key', hemos de escribir:
PermisoConduccion clave = new PermisoConduccion();
clave.setType("C ");
clave.setLevel(1);
setValue("drivingLicence.KEY", clave.toString());
Es mejor usar la última forma, porque funciona con POJOs y EJBs.

Hibernate: Referencias con columnas no nula como clave foránea

En la versión EJB si tenemos una referencia a otra entidad cuya clave está compuesta por tipos primitivos, el código se genera de tal forma que no se graban nulos en la base de datos, aunque asignemos un nulo a la referencia.
En la versión Hibernate si asignamos nulo a una referencia, se graban valores nulos en la base de datos.
Por supuesto, el comportamiento de la versión Hibernate es más correcto, pero podemos hacer que en Hibernate se eviten los nulos en la base de dato, simplemente usando conversores en el mapeo de referencia (ver sección 6.3 de la guía de referencia).
Es decir, quizás necesitemos añadir algunos conversores a nuestra referencias para migrar nuestras aplicaciones de EJB2 a Hibernate.

Cambiar la sección activa

xava_activeSection ya no se usa para cambiar la sección activa. Ahora si queremos cambiar la sección activa tenemos que llamar al método setActiveSection de la vista deseada (org.openxava.view.View).

IAggragetOidCalculator

El método setContainerKey se ha renombrado a setContainer. Y su semántica también. Ahora se recibe el objeto contenedor en vez de la clave. De esta manera este calculador es consistente en la versión EJB2 y POJO (si clases para clave).

Para migrar de OpenXava 1.2 a OpenXava 1.2.1

Generación Hibernate

Ahora cuando la generación EJB se hace, la generación de código hibernate se realiza también (aunque la versión hibernate todavía no se soporta al 100%).
Aunque uses solo la versión EJB necesitas hacer una pequeña adaptación en tu proyecto:
El hibernate.cfg.xml ha de ser:
<!DOCTYPE hibernate-configuration PUBLIC
   "-//Hibernate/Hibernate Configuration DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  <hibernate-configuration>
   <session-factory>
       <property name="hibernate.connection.datasource">@datasource.prefix@/@datasource@</property>
       <property name="hibernate.dialect">@hibernate.dialect@</property>
       <property name="hibernate.show_sql">false</property>
   </session-factory>
</hibernate-configuration>
Adicionalmente tienes que incluir la propiedad hibernate.dialect en tus archivos de configuración:
hibernate.dialect=org.hibernate.dialect.HSQLDialect

Sintaxis XML de OpenXava

Para migrar de OpenXava 1.1 a OpenXava 1.2

Código generado

Ahora las interfaces remote de EJB tienen el sufijo Remote, y la interfaz de negocio generada para cada componente (por ejemplo ICliente) no contiene todos los métodos de la interface remota.
Esto es para permitir que la futura versión 2 de OpenXava pueda trabajar con EJB e Hibernate en el mismo projecto y a la vez.
Para adaptar el código hay que:
Para corregir los errores de sintaxis se tiene que hacer cambios como éste:
Cliente cliente = ClienteUtil.getHome().findByNombre("PEPE");
String nombre = cliente.getNombre();
Cambiarlo por:
ICliente cliente = ClienteUtil.getHome().findByNombre("PEPE");
String nombre = cliente.getNombre();
Si se usan métodos específicos de EJB hay que moldear a la interfaz remota:
Cliente cliente = ClienteUtil.getHome().findByNombre("PEPE");
ClienteKey key = cliente.getPrimaryKey();
Cambiarlo por:
ClienteRemote cliente = ClienteUtil.getHome().findByNombre("PEPE");
ClienteKey key = cliente.getPrimaryKey();
Es decir, cambiar Cliente por ICliente cuando sea posible, de no serlo cambiarlo por CustomeRemote.

Pruebas JUnit

Otros

Para migrar de OpenXava 1.0 a OpenXava 1.1

APIs

Pruebas junit