openxava / documentation / Migration to v6.x

If you want to migrate to OpenXava 7.0 or newer look at the new migration instructions

How to update your project to the latest OpenXava 6.x?


Migration from OpenXava 6.6.2 to OpenXava 6.6.3

No issues.

Migration from OpenXava 6.6.1 to OpenXava 6.6.2

No issues.

Migration from OpenXava 6.6 to OpenXava 6.6.1

No issues.

Migration from OpenXava 6.5.3 to OpenXava 6.6

No issues.

Migration from OpenXava 6.5.2 to OpenXava 6.5.3

No issues.

Migration from OpenXava 6.5.1 to OpenXava 6.5.2

Four digits for year in all locales (for JUnit tests)

Until now we used four digits for year only for selected locales. From now on we'll use four digits for year for all locales. Therefore, if you use a locale that used two digits for year (like English for example) you have to adjust your JUnit tests, changing, for example, this:
assertValue("date", "5/25/21");
By this:
assertValue("date", "5/25/2021");
Note as we changed 21 by 2021.

Migration from OpenXava 6.5 to OpenXava 6.5.1

No issues.

Migration from OpenXava 6.4.2 to OpenXava 6.5

Only queries saved explicitly are stored in list mode (for JUnit tests)

In v6.5 only the queries saved explicitly are stored in list, so JUnit tests that rely on that to reuse a previously used filter will fail. That is, this test code now fails:
setConditionValues("1");
execute("List.filter"); // This does not save "Number = 1" automatically

// Here you do more stuff

selectListConfiguration("Number = 1"); // FAILS IN v6.5
The solution is to save the query explicitly, thus:
setConditionValues("1");
execute("List.filter"); 

execute("List.saveConfiguration"); // ADD THESE LINES TO SAVE...
execute("SaveListConfiguration.save"); // ...THE QUERY EXPLICITLY

// Here you do more stuff

selectListConfiguration("Number = 1"); // Now it works

Action for change query name in list no longer show for 'All' query (for JUnit tests)

Given that only the queries saved explicitly are saved in list mode, only the explicitly saved queries can be renamed or removed. Also, the 'All' query cannot be renamed or removed. These changes does not require you modify your application code. However, you must adapt your JUnit tests to the new user interface, because when you enter in a module in list mode, usually the 'All' query is shown, and so the action to Change name/remove (List.changeConfiguration) is no longer there. Therefore, if you use assertActions() in your tests you should adapt the list of actions, removing List.changeConfiguration, thus:
String [] listActions = {
    "Print.generatePdf",
    "Print.generateExcel",
    "ImportData.importData", 
    "CRUD.new",
    "CRUD.deleteSelected",
    "CRUD.deleteRow",
    "List.filter",
    "List.orderBy",
    "List.viewDetail",
    "List.hideRows",
    "List.sumColumn",
    // "List.changeConfiguration", // REMOVE THIS LINE
    "List.changeColumnName", 
    "ListFormat.select" 
}; 
assertActions(listActions);

Migration from OpenXava 6.4.1 to OpenXava 6.4.2

No issues.

Migration from OpenXava 6.4 to OpenXava 6.4.1

No issues.

Migration from OpenXava 6.3.2 to OpenXava 6.4

Modify Deployment Assembly to run Tomcat inside Eclipse

If you still run Tomcat inside Eclipse with Eclipse IDE for Enterprise Java Developers, you have to modify the Deployment Assembly of your project in order to not include OpenXava and Addons as dependent projects. For that, inside Eclipse click with right mouse button on your project, and choose Properties > Deployment Assembly, then you get a dialog like this: 
There select Addons and OpenXava, and click on Remove button. Then click on Apply and Close.

Automatic label for reference member in list improved (for JUnit tests)

The automatic label for members of references now makes the first letter uppercase and the rest lowercase. This does not affect your application code, but if you verify the labels of some list maybe you have to do some adjust in your JUnit tests, such as changing this assert:
assertLabelInList(0, "Year of Invoice");
By this one:
assertLabelInList(0, "Year of invoice");

Migration from OpenXava 6.3.1 to OpenXava 6.3.2

No issues.

Migration from OpenXava 6.3 to OpenXava 6.3.1

Closing dialog does not lose collection pagination (for JUnit tests)

Really this is a fix, but if your JUnit tests rely on this bug, you have to adapt them. For example, in the next JUnit code you should remove the second pagination action:
execute("List.goNextPage", "collection=myCollection");
execute("Collection.edit", "row=10,viewObject=xava_view_myCollection");
setValue("name", "Modified name");
execute("Collection.save");
// execute("List.goNextPage", "collection=myCollection"); // REMOVE THIS LINE
assertValueInCollection("myCollection", 0, 0, "Modified name");
Because now after closing the dialog the collection remains in the same page, so you no longer need to reposition it.

Migration from OpenXava 6.2.2 to OpenXava 6.3

Welcome page for Internet Explorer

We have moved colors in CSS to variables. Variables are not supported in Internet Explorer 11, fortunately it's very easy to add CSS variable support to IE11 using a JS library. We have done it for all OpenXava code, but Welcome page (welcome.jsp) is yours, so you have to add the next code to welcome.jsp in order it can use the OpenXava styles well with IE9:
<% if (org.openxava.web.Browsers.isIE(request)) { %>
<script type='text/javascript' src="<%=request.getContextPath()%>/xava/js/css-vars-ponyfill.js?ox=<%=oxVersion%>"></script>
<script type='text/javascript'>cssVars({ }); </script>	
<% } %>

Welcome page for root context

Since v6.3 you can run your application in root context, that is without using the application name in the browser URL. All the OpenXava code has been adapted for that, but Welcome page (welcome.jsp) is yours, so you have to change the next code in welcome.jsp:
String applicationName = request.getContextPath().substring(1);
MetaApplication metaApplication = MetaApplications.getMetaApplication(applicationName);
By:
MetaApplication metaApplication = MetaApplications.getMainMetaApplication();
This is only needed if you want to run your application in the root context.

Migration from OpenXava 6.2.1 to OpenXava 6.2.2

No issues.

Migration from OpenXava 6.2 to OpenXava 6.2.1

No issues.

Migration from OpenXava 6.1.2 to OpenXava 6.2

Datasource definition in web/META-INF/context.xml of project

So, if you do an updateOX on your project and try it in the Tomcat inside Eclipse, it will fail. Now you have to define your datasource in web/META-INF/context.xml of your project. This is the datasource for development, in production (that is in a Tomcat outside Eclipse) the datasources defined in conf/context.xml of Tomcat take preference, so you have not to modify datasources in production, just in development.

New editor for PHOTO, IMAGE, IMAGES_GALLERY, FILE and FILES stereotypes (for JUnit tests)

The new editor does not require any change in your application code, but given that the actions of the controllers ImageEditor, Gallery, LoadImageIntoGallery, etc. no longer exist you should adapt the tests where you upload files. For example, if you have this test code to load an image:
execute("ImageEditor.changeImage", "newImageProperty=image"); 
String imageURL = System.getProperty("user.dir") + "/test-images/cake.gif";
setFileValue("newImage", imageURL);
execute("LoadImage.loadImage");
You should rewrite it in this way:
uploadFile("image", "test-images/cake.gif");
Or for the gallery:
execute("Gallery.edit", "galleryProperty=photos");
execute("Gallery.addImage");
String imageURL = System.getProperty("user.dir") + "/test-images/foto-javi.png";
setFileValue("newImage", imageURL);
execute("LoadImageIntoGallery.loadImage");
execute("Gallery.close");
You should rewrite it in this way:
updateFile("photos", "test-images/foto-javi.png");
The same for FILE and FILES stereotypes. In ModuleTestBase now we have the methods uploadFile(), removeFile(), assertFile(), assertNoFile() and assertFilesCount() to deal with the upload editors.

The new editor for IMAGES_GALLERY stereotype is inline and with frame

So it is not longer displayed as a simple property, it means that maybe you have to adapt the layout of some of your views. For example, if you have:
@View(members="number, description, screenshots, date")
Where screenshots is an IMAGES_GALLERY property, now you should rewrite it in this way:
@View(members="number, description; screenshots; date")
Leaving a single line for the screenshots property.

The new editor for FILES stereotype fills all the width of the view

It means that maybe you have to adapt the layout of some of your views. For example, if you have:
@View(members="number, description, attachments, date")
Where attachments is a FILES property, now you should rewrite it in this way:
@View(members="number, description; attachments; date")
Leaving a single line for the attachments property.
Also you should not use FILES in a view aligned by column (that one with a # before members), that is you should change:
@View(members=
    "datasheet [ #title;" +	
    "   releaseDate, director;"   +
    "   writers, starring;"    +
    "   scripts;" + // FILES
    "]"
)
Where scripts is a FILES property, by:
@View(members=
    "datasheet [ #title;" +	
    "   releaseDate, director;"   +
    "   writers, starring;"    +
    "]" +
    "scripts [ scripts ]"
)
Note as we put the FILES property, scripts, in its own group.

Migration from OpenXava 6.1.1 to OpenXava 6.1.2

No issues.

Migration from OpenXava 6.1 to OpenXava 6.1.1

First module page loaded via AJAX (only if you use HtmlUnit API)

Now the first page loading is done via AJAX, so if you use directly the HtmlUnit in your tests you have to wait until the AJAX request be complete when load a page. This can be accomplished calling waitAJAX(), in this way:
HtmlPage page = (HtmlPage) getWebClient().getCurrentWindow().getEnclosedPage();
waitAJAX(); // ADD THIS LINE BEFORE USING page

If you tests uses exclusively the methods on ModuleTestBase you don't need to change anything.

Migration from OpenXava 6.0.2 to OpenXava 6.1

Bean Validation upgraded from 1.1 to 2.0

Bean Validation 2.0 is compatible with 1.1, so most of your code will continue working as always. However, Bean Validation 2.0 includes some new annotations that were before in Hibernate Validator, so if you imported both Hibernate Validator and Bean Validation maybe some of your code will not compile. For example:

import javax.validation.constraints.*;
import org.hibernate.validator.constraints.*; 

public class MyClass {

    // @NotBlank // NOW IT PRODUCES COMPILATION ERROR
@javax.validation.constraints.NotBlank // QUALIFY THE ANNOTATION
    private String mainStreet;

Now @NotBlank is in both javax.validation.constraints and org.hibernate.validator.constraints. Just remove the org.hibernate.validator.constraints import or, if you still need Hibernate Validator, qualify the @NotBlank annotation (that is use @javax.validation.constraints.NotBlank).

EL libraries upgrade for Tomcat 7 or any other old application server

If you're using Tomcat 7 copy el-api.jar and jasper-el.jar from the Tomcat lib folder included in OpenXava (or any Tomcat 9) to the lib folder of your Tomcat 7. This is required by the latest Hibernate Validator version. If you use another old application server (as an old WebLogic version) and you don't know how to upgrade it, just copy el-api.jar and jasper-el.jar to the WEB-INF/lib folder of your project.

HtmlUnit upgraded from 2.15 to 2.32

If you uses directly the HtmlUnit API, via getWebClient() or getHtmlPage() from ModuleTestBase, you have to adapt your code to the new HtmlUnit. We have collected here some changes we have noted.

For example, the methods starting by getHtmlElement... now are getElement..., just you need to remove the Html. So, you should change:

HtmlElement iCharts = chartsLink.getHtmlElementsByTagName("i").get(0);

By:

HtmlElement iCharts = chartsLink.getElementsByTagName("i").get(0);

The click() method no longer fires the onclick event. So you have to change:

button.click();

By:

getHtmlPage().executeJavaScript(button.getOnClickAttribute());

Changing the value of a HtmlInput does not throw the onchange event, so you have to change:

input.setValueAttribute(value);
By:
input.setValueAttribute(value);
if (!Is.emptyString(input.getOnChangeAttribute())) {
    input.fireEvent(Event.TYPE_CHANGE);
}

And possibly more things, consult the HtmlUnit doc.

ModuleTestBase.setLocale() resets the module

Because of the new HtmlUnit we no longer have a way to change the language without resetting the module. So maybe you have to adapt some of your tests. For example:

execute("CRUD.new");
...
setLocale("es"); // Here the module is reset
execute("CRUD.new"); // ADD THIS LINE
...

In this case the setLocale() reset the module starting in list mode, so we call to CRUD.new in order the test continue working as always.

Hibernate upgraded from 4.3 to 5.3

Given we use JPA API in our applications most of our code will work without any change. However, maybe we find some details that work slightly differently. For example, for this entity definition:

public class Customer {
    @OneToMany
    private Collection<Seller> sellers;

The next code no longer works:

customer.setSellers(Collections.emptySet());
Now you have to write:
customer.setSellers(new ArrayList<>());

Maybe, you find another little details you have adjust, consult the Hibernate doc. Anyways, we explain the more important ones in the points below.

Duplicate foreign keys if you uses automatic schema generation

Hibernate 5.3 has a bug that duplicates the foreign keys if you use hibernate.hbm2ddl.auto=update against the DB you were using with Hibernate 4.3. If you database is tolerant with duplicate foreign keys there is no problem, otherwise you can get some warnings or even errors. By now, the only solution to this is to remove all the foreign keys of your database by hand, so Hibernate creates them correctly on starting.

Automatically updating schema on startup requires a default schema

Since Hibernate 5.3 the next configuration for persistence.xml does not work:

<properties>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>

You have to define a hibernate.default_schema in order it work correctly. If you don't use a schema just define the default schema for your database, for example PUBLIC for HSQLDB, like this:

<properties>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.default_schema" value="PUBLIC"/>
</properties>
On the other hand, the updateSchema ant task work nicely even without schema.

MySQL does no longer recognize default schema

With Hibernate 5.3 hibernate.default_schema no longer has effect for MySQL, now you have to use hibernate.default_catalog instead. Since OpenXava 6.1.2 we have modified the OpenXava APIs in order to work as always, recognizing hibernate.default_schema even for MySQL. However, the automatic schema generation on startup (that is hibernate.hbm2dll.auto=update or javax.persistence.schema-generation.database.action=update) is a Hibernate business, so we cannot fix it. If you use it, you should change hibernate.default_schema by hibernate.default_catalog.

Summarizing, if you use MySQL change in persistence.xml:

<properties>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.default_schema" value="COMPANYB"/>
</properties>

By:

<properties>
    <property name="hibernate.hbm2ddl.auto" value="update"/>
    <property name="hibernate.default_catalog" value="COMPANYB"/>
</properties>

Note, hibernate.default_catalog instead of hibernate.default_schema. Only for MySQL.

@GeneratedValue(strategy=GenerationType.AUTO) is no longer IDENTITY by default

In Hibernate 5.3 @GeneratedValue(strategy=GenerationType.AUTO) is no longer IDENTITY by default, at least for HSQLDB. So, if you use HSQLDB and don't want to change your tables structure you have to change this:

@Id 
@GeneratedValue(strategy=GenerationType.AUTO)// Or just @GeneratedValue private int id;

By this:

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY) private int id;

In your id properties with GenerationType.AUTO.

Method signature changed for UserType and CompositeUser of Hibernate

In Hibernate 5.3 they have changed the method signatures of the type converters, those used in @Type annotation. If you have created your own Hibernate custom converter you have to make some slight modifications in your method signatures, concretely you have to change SessionImplementer by SharedSessionContractImplementor as parameter. For example, you should change this line:

public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor sessionImplementor, Object owner) 
    throws HibernateException, SQLException {

By this one:

public Object nullSafeGet(ResultSet resultSet, String[] names, SharedSessionContractImplementor sessionImplementor, Object owner)
    throws HibernateException, SQLException {

The same for all methods that use SessionImplementer of any UserType or CompositeUser implementation.

Liferay configuration

In order the new Hibernate 5.3 works with Liferay you have to create a file portal-ext.properties in the webapps/ROOT/WEB-INF/classes folder of the Tomcat in your Liferay, with the next entry:

portal.security.manager.strategy=none           

Migration from OpenXava 6.0.1 to OpenXava 6.0.2

No issues.

Migration from OpenXava 6.0 to OpenXava 6.0.1

No issues.

Migration from OpenXava 5.9.1 to OpenXava 6.0

New Welcome and FirstSteps pages

If you have not modified your Welcome and FirstSteps pages then remove web/naviox/welcome.jsp and web/naviox/firstSteps.jsp from your project before doing the updateOX. If you have your own Welcome or FirstSteps page then edit them to change the references to naviox.css (as explained below) and remove all references to NaviOXStyle Java class that no longer exists.

naviox.css renamed as light.css

Moreover, it has been moved from Addons to OpenXava. So, if you use it in some custom JSP, such as welcome.jsp, you have to change:

<link href="<%=request.getContextPath()%>/naviox/style/naviox.css?ox=<%=oxVersion%>" 
rel="stylesheet" type="text/css">
By:
<link href="<%=request.getContextPath()%>/xava/style/light.css?ox=<%=oxVersion%>"
    rel="stylesheet" type="text/css">

Still better you can include the CSS of the current theme instead of an ad hoc CSS, in this way:

<link href="<%=request.getContextPath()%>/xava/style/<%=XavaPreferences.getInstance().getStyleCSS()%>?ox=<%=oxVersion%>"
    rel="stylesheet" type="text/css">

View.findObject() returns true if does not find the object instead of throwing an exception

Therefore you have to change:
getView().findObject();
By:
if (!getView().findObject()) {
    addError("object_with_key_not_found")
}
In the code of your actions.

Modes no longer exist from the user perspective (for JUnit tests)

Modes no longer exist for the user. In list he can click on a row or on New to go detail. In detail there is a link "List" on left, no more. Split is no longer available. These changes does not require you modify your application code. The old controllers modes, Mode, DetailOnly, Void, no longer exist but OpenXava assumes Mode instead, so you code will run fine without any change. However, you must adapt your JUnit tests to the new user interface.
The main change is that Mode.detailAndFirst no longer exist, so you have to change in your tests:
execute("Mode.detailAndFirst"); -- Change by --> execute("List.viewDetail", "row=0");
That is, instead of clicking on the Detail tab, now the test clicks on the first row. Equivalent for most cases.
The mode controllers, Mode, DetailOnly, Void, no longer exist, Mode is assumed instead. So you have to change in your tests:
execute("DetailList.detailAndFirst"); -- Change by --> execute("List.viewDetail", "row=0"); 
execute("DetailList.list"); -- Change by --> execute("Mode.list");
The action Mode.split no longer exist, you cannot use it in your test:
execute("Mode.split"); // Remove this line from your test, maybe you have to adapt your test
Given that Mode.detailAndFirst and Mode.split no longer exist, if you use assertActions() should adapt the list of actions:
private String [] listActions = {
    "Print.generatePdf",
    "Print.generateExcel",
    "ImportData.importData",
    "CRUD.new",
    "CRUD.deleteSelected",
    "CRUD.deleteRow",
    // "Mode.detailAndFirst",     // REMOVE THIS LINE
    // "Mode.split",              // REMOVE THIS LINE
    "List.filter",
    "List.orderBy",
    "List.viewDetail",
    "List.hideRows",
    "List.sumColumn",
    "List.changeConfiguration",
    "List.changeColumnName",
    "ListFormat.select"
}; assertActions(listActions);

Main entity validated before opening the dialog to create a new item for a collection (for JUnit tests)

That is, the JUnit code:
execute("CRUD.new"); 
execute("Collection.new", "viewObject=xava_view_buildings");
Could fail, because if we don't fill any field surely the validation will fail, because now validation is done on main entity on Collection.new.
To solve this you have two options. First, fill the required fields:
execute("CRUD.new");
setValue("name", "SOMETHING"); // ADD THIS
execute("Collection.new", "viewObject=xava_view_buildings");
It would work if name is the only required property. If there are many required properties maybe the second option, look for an existent entity, is better:
execute("List.viewDetail", "row=0"); // Instead of: execute("CRUD.new");
execute("Collection.new", "viewObject=xava_view_buildings");

Migration from OpenXava 5.9 to OpenXava 5.9.1

No issues.

Migration from OpenXava 5.8.1 to OpenXava 5.9

New actions in collections (for JUnit tests)

The collections have new actions available for the users (CollectionCopyPaste.cut and CollectionCopyPaste.paste), therefore if you test for all present actions in your junit tests, you need to modify it in order to take into account the new CollectionCopyPaste.cut action. CollectionCopyPast.paste is hidden by default, so you can ignore it. Moreover, List.sumColum now is always present even if the collection is empty:
String [] actions = {
    "Navigation.previous",
    "Navigation.first",
    "Navigation.next",
    "CRUD.new",
    "CRUD.save",
    "CRUD.delete",
    "CRUD.refresh",
    "Mode.list",
    "Mode.split",
    "Collection.new",
    "Collection.removeSelected",
    "CollectionCopyPaste.cut", // ADD THIS ENTRY
    "Print.generatePdf",
    "Print.generateExcel",
    "List.filter",
    "List.orderBy",
    "List.sumColumn", // ALWAYS PRESENT, EVEN IF COLLECTION IS EMPTY
    "List.changeColumnName"
};
assertActions(actions);

Booleans are rendered with their label instead of a check in lists

Until now when a boolean was true in the list, the cell shows a check icon and if it is false nothing. From now on, if the boolean is true its label will be shown in the cell, that is for a property named paid, "Paid" will be shown in the cell. This change does not require any modification in your application code, however maybe you have to change some of your JUnit tests for lists and collections. For example, if you have the next line in your test:
assertValueInList(2, 4, "Yes");
You should change it by:
assertValueInList(2, 4, "Paid");
If the property label is "Paid".
And for the false case, you should change:
assertValueInList(2, 4, "No");
By:
assertValueInList(2, 4, "");
On the other hand if you want to keep the old behavior, just add the next entry in your editors.xml file:
<editor url="booleanEditor.jsp">
  <formatter class="org.openxava.formatters.BooleanFormatter" >
    <set property="nullAsFalse" value="true"/>
  </formatter>
  <list-formatter class="org.openxava.formatters.BooleanIconListFormatter" />
  <for-type type="boolean" />
  <for-type type="java.lang.Boolean" />
</editor>
Note the use of BooleanIconListFormatter for list formatter.

Welcome page and Sign In page are separated

Now the content of welcome.jsp is shown when you go to the root of the application. welcome.jsp fills all the page, so you should modify your current welcome.jsp to include the <head>, import the needed CSSs and include a link to the Sign In page (m/SignIn). Look at Addons/web/naviox/welcome.jsp as example.

Migration from OpenXava 5.8 to OpenXava 5.8.1

No issues.

Migration from OpenXava 5.7.1 to OpenXava 5.8

New actions in list mode (for JUnit tests)

The list mode has new actions available for the users (List.changeColumnName and ImportData.importData), therefore if you test for all present actions in your junit tests, you need to modify it in order to take into account the new List.changeColumnName and ImportData.importData actions:
private String [] listActions = {
    "Print.generatePdf",
    "Print.generateExcel",
    "ExtendedPrint.myReports",
    "CRUD.new",
    "CRUD.deleteSelected",
    "CRUD.deleteRow",
    "Mode.detailAndFirst",
    "Mode.split",
    "List.filter",
    "List.orderBy",
    "List.viewDetail",
    "List.hideRows",
    "List.sumColumn",
    "List.changeConfiguration",
    "ListFormat.select",
    "List.changeColumnName", // ADD THIS ENTRY
    "ImportData.importData"  // ADD THIS ENTRY
};
assertActions(listActions);

Delete action is not available while creating a new element (for JUnit tests)

In v5.8 when the user clicks on New the Delete action is hidden. This does not affect your application code but if you use assertActions() in your tests maybe you have to adapt them:
String [] actionsAfterNew = {
 "Navigation.previous",
 "Navigation.first",
 "Navigation.next",
 "CRUD.new",
 "CRUD.save",
 // "CRUD.delete", // REMOVE THIS LINE
 "CRUD.refresh",
 "Mode.list",
 "Mode.split",
 "List.filter",
 "List.orderBy",
 "Print.generatePdf",
 "Print.generateExcel"
};
assertActions(actionsAfterNew);

Search action no longer available in detail mode (for JUnit tests)

If you use assertActions() in your tests you should adapt them:
String [] actions = {
 "Navigation.previous",
 "Navigation.first",
 "Navigation.next",
 "CRUD.new",
 "CRUD.save",
 "CRUD.delete",
 // "CRUD.search", // REMOVE THIS LINE
 "CRUD.refresh",
 "Mode.list",
 "Mode.split",
};
assertActions(actions);
If you use CRUD.search in your test you can change it by CRUD.refresh, that is change:
execute("CRUD.search");
setValue("number", "123");
execute("Search.search");
By:
setValue("number", "123");
execute("CRUD.refresh");
Moreover, if you want that the search action comes back use the new SearchForCRUD controller that just contains the classic seach action. To define a module with search in application.xml add the SearchForCRUD controller:
<module name="Delivery">
    <model name="Delivery"/>
    <controller name="Typical"/>
    <controller name="SearchForCRUD"/> <!-- ADD THIS LINE -->
</module>
Another option si to define it in controllers.xml in this way:
<controller name="Author">
    <extends controller="Typical"/>
    <extends controller="SearchForCRUD"/> <!-- ADD THIS LINE -->
    <action name="doSomething"
        class="com.mycompany.test.actions.DoSomethingAction" />
</controller>
Even if you add the search action back with SearchForCRUD you have to change your JUnit tests because search is no longer in CRUD but in SearchForCRUD. Therefore you have to change:
execute("CRUD.search");
By:
execute("SearchForCRUD.search");
Also we have a TypicalWithSearch controller that have all the Typical action plus search, just as the old Typical. If you want to use it by default write the next code at the beginning of your application.xml:
<default-module>
    <controller name="TypicalWithSearch"/>
</default-module>

Modules with no rows starts executing new action (for JUnit tests)

You should touch JUnit tests with modules without rows, because they now starts in detail mode. For example, you should change a code like this:
public void testCreateExamWithAtLeastOneQuestion() throws Exception {
  assertListRowCount(0); // NOW THIS LINE FAILS
  execute("CRUD.new");
  setValue("name", "ADMISSION");
  execute("CRUD.save");
  ...
}
If the module has no rows, now it starts in detail mode so the first line will fail. We can just change to list mode at the beginning:
public void testCreateExamWithAtLeastOneQuestion() throws Exception {
  execute("Mode.list"); // ADD THIS LINE
  assertListRowCount(0);
  execute("CRUD.new");
  setValue("name", "ADMISSION");
  execute("CRUD.save");
  ...
}
Or if you test goes directly to detail mode, like in this example, just remove the first part of the test:
public void testCreateExamWithAtLeastOneQuestion() throws Exception {
  // assertListRowCount(0); // REMOVE THIS LINE
  // execute("CRUD.new"); // REMOVE THIS LINE
  setValue("name", "ADMISSION");
  execute("CRUD.save");
  ...
}

Migration from OpenXava 5.7 to OpenXava 5.7.1

No issues.

Migration from OpenXava 5.6.1 to OpenXava 5.7

Action List.changeConfigurationName renamed as List.changeConfiguration (for JUnit tests)

The list action List.changeConfigurationName now is List.changeConfiguration, therefore if you test for all present actions in your junit tests, you need to modify the name of this action:
private String [] listActions = {
  "Mode.detailAndFirst",
  "Mode.split",
  "List.filter",
  "List.orderBy",
  "List.viewDetail",
  "List.hideRows",
  "List.sumColumn",
  // "List.changeConfigurationName" // REMOVE THIS ENTRY
  "List.changeConfiguration" // ADD THIS ENTRY
};
assertActions(listActions);

Improved default properties for list and collections (for JUnit tests)

Until now when @Tab for list, or @ListProperties for collections, is omitted by default OpenXava shows all the plain properties of the entity. Since v5.7 when @Tab/@ListProperties is not present the properties to show are the plain ones, the ids of the references, the name, description or title of the references or if not present the first not id property of the reference. Moreover, the plain properties that are just oids are excluded.
For example, if we have this class without @Tab:
@Entity
public class Invoice {
 private int year;
 private int number;
 private Date date;
 @ManyToOne
 private Customer customer;
 
 @Stereotype("FILES") @Column(length=32)
 private String files;
 
 ...
}
In previous versions we get in list: year, number, date, files
In v5.7 we get: year, number, date, customer.number, customer.name
If you have JUnit tests againts entities without @Tab maybe you'll have to adapt them.

@NewAction no longer define the add action in regular @OneToMany collections

Since v5.7 @OneToMany collections without cascade REMOVE have available at the same time a 'New' action to create new elements and a 'Add' action to add elements from existing ones. Before v5.7 only the 'Add' action was available and it could be defined using @NewAction. Now we have a new annotation, @AddAction, for 'Add' action and we use the old @NewAction only for 'New' action.
You should change @NewAction by @AddAction in collections without cascade REMOVE. Change:
@NewAction("Invoice.addDeliveries")
@OneToMany(mappedBy="invoice")
private Collection<Delivery> deliveries;
By:
@AddAction("Invoice.addDeliveries")
@OneToMany(mappedBy="invoice")
private Collection<Delivery> deliveries;

Collections of entities with no REMOVE cascade allow to edit the elements (for JUnit tests)

You don't need to change your application code, just adapt your JUnit tests changing:
execute("Collection.view", "row=1,viewObject=xava_view_customers");
By:
execute("Collection.edit", "row=1,viewObject=xava_view_customers");
Note, now it's not "Collection.view" but "Collection.edit".

Automatic label for references in list optimized (for JUnit tests)

When in a list we have a property from a reference and the property name is "name", "description" or "title", the property name is omitted, OpenXava shows just the reference name. That is, instead of "Name of Customer" now is just "Customer". This does not affect your application code at all, but if you test list labels in your JUnit tests you should adapt them.
Change this:
assertLabelInList(4, "Name of Customer");
By this:
assertLabelInList(4, "Customer");

Migration from OpenXava 5.6 to OpenXava 5.6.1

No issues.

Migration from OpenXava 5.5.1 to OpenXava 5.6

The action ExtendedPrint.myReports is no longer available by default (for JUnit tests)

Therefore if you test for all present actions in your JUnit tests, you need to modify it removing ExtendedPrint.myReports from the list:
private String [] listActions = {
    "Print.generatePdf",
    "Print.generateExcel",
    // REMOVE THIS LINE "ExtendedPrint.myReports",
    "CRUD.new",
    "CRUD.deleteSelected",
    ...
};
assertActions(listActions);
Though the action is not available by default, it still exists in OpenXava and works perfectly. Indeed there is a new controller TypicalExtendedPrint to facilitate its use. If you want to continue using the My reports feature just change Typical by TypicalExtendedPrint in your application.xml and controllers.xml, even you can declare it as default controller.

New action in list (for junit tests)

The list has a new action available for the users (List.changeConfigurationName), therefore if you test for all present actions in your junit tests, you need to modify it in order to take into account the new List.changeConfigurationName action:
private String [] listActions = {
  "Mode.detailAndFirst",
  "Mode.split",
  "List.filter",
  "List.orderBy",
  "List.viewDetail",
  "List.hideRows",
  "List.sumColumn",
  "List.changeConfigurationName" // ADD THIS ENTRY
};
assertActions(listActions);

Migration from OpenXava 5.5 to OpenXava 5.5.1

Needed to call super inside setUp() of tests before using JPA

Since v5.5.1 the JPA initialization ModuleTestBase tests is done in the setUp() method, so if you use JPA inside a setUp() method you have to call super before. That is, if you have a code like this in your test:
protected void setUp() throws Exception {
    createEntitiesUsingJPA(); // Now it fails, because JPA is not still initialized
    super.setUp();
}
Change it by:
protected void setUp() throws Exception {
    super.setUp(); // JPA is initialized here
    createEntitiesUsingJPA();
}

Migration from OpenXava 5.4.1 to OpenXava 5.5

@DescriptionsList combos are not longer HTML select (only if you use HtmlUnit API)

Combos for @DescriptionsList are now created with a HTML input text plus some JavaScript code and CSS to emulate a combo. This does not require any change in your application code, it even does not require that you change your jUnit tests if you just use the ModuleTestBase provided methods. However, if you use the HtmlUnit API directly, for example by means of getHtmlPage() or getWebClient() in your tests, and you manage a @DescriptionList combo. Then you have to adjust your code, changing:
form.getSelectByName("ox_MyApp_MyModule__myReference___id").setSelectedAttribute("TheValue", true);
By:
HtmlInput comboInput = form.getInputByName("ox_MyApp_MyModule__myReference___id");
comboInput.setValueAttribute("TheValue");
((HtmlInput) comboInput.getPreviousElementSibling()).setValueAttribute("Something"); // A trick to avoid that JavaScript reset the real value
((HtmlInput) comboInput.getNextElementSibling()).setValueAttribute("Something"); // A trick to avoid that JavaScript reset the real value

Migration from OpenXava 5.4 to OpenXava 5.4.1

No issues.

Migration from OpenXava 5.3.2 to OpenXava 5.4

Icons instead of images for actions

Since v5.4 the standard actions of OpenXava use icons from Material Design Icons instead of gif or png images. The image attribute of <action/> in controllers.xml continue to work as always, however we have a new attribute icon that is the one used in the standard actions. The effect is that in your application all the standard actions will use the new monochrome icons and your own actions will use the old colorful gif and png images. This mix could be a little ugly, to fix it just change image by icon in your actions. For example, change:
<action name="delete" mode="detail" confirm="true"
    class="com.mycompany.myapp.actions.MyDeleteAction"
    image="delete.gif"
    keystroke="Control D"/>
By this:
<action name="delete" mode="detail" confirm="true"
    class="com.mycompany.myapp.actions.MyDeleteAction"
    icon="delete"
    keystroke="Control D"/>
To see all available icons look at Material Design Icons.
On the other hand, if your prefer to continue with the old fashion color icons, just add the next line in xava.properties:
useIconsInsteadOfImages=false
Then all the actions, included the standard ones, will use the old colorful images.

Migration from OpenXava 5.3.1 to OpenXava 5.3.2

No issues.

Migration from OpenXava 5.3 to OpenXava 5.3.1

HSQLDB jar moved from OpenXavaTest to OpenXava

If you reference this jar you have to change the path. For example, if you uses HSQLDB in some of your projects, you should change in updateSchema target of your build.xml this:
<property name="schema.path" value="../OpenXavaTest/lib/hsqldb.jar"/>
By this:
<property name="schema.path" value="../OpenXava/lib/hsqldb.jar"/>

Migration from OpenXava 5.2.1 to OpenXava 5.3

Hibernate upgraded to 4.3

If you use JPA API or basic use of Hibernate API you have to do nothing. However, if you use advanced Hibernate features maybe this upgrade affects you.
For example, if you have your own Hibernate types (UserType), you have to change in your type definition this:
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
By:
public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor sessionImplementor, Object owner) throws HibernateException, SQLException {
And this:
public void nullSafeSet(PreparedStatement ps, Object value, int index) throws HibernateException, SQLException {
By:
public void nullSafeSet(PreparedStatement ps, Object value, int index, SessionImplementor sessionImplementor) throws HibernateException, SQLException {
Of course, if you call these methods you have to adapt the calling code too. For example, a code like this:
((UserType) hibernateType).nullSafeSet(ps, o, 1);
Now it would be:
((UserType) hibernateType).nullSafeSet(ps, o, 1, null);
Note that sending a null for the new extra parameter is enough.
Moreover, instead of Hibernate.INTEGER you have to use IntegerType.INSTANCE.
The way of registering events has changed, it affects you only if you use XML components with the JPA API. In this case you have to remove the event registration from the persistence.xml, as following:
<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
 
    <properties>
        <property name="hibernate.ejb.cfgfile" value="/hibernate-jpa.cfg.xml"/>
        <!-- REMOVE THE NEXT LINES
        <property name="hibernate.ejb.event.pre-insert" value="org.openxava.hibernate.impl.CalculatorsListener, org.openxava.hibernate.impl.ReferenceConverterToDBListener, org.openxava.hibernate.impl.DefaultValueCalculatorsListener"/>
        <property name="hibernate.ejb.event.pre-update" value="org.openxava.hibernate.impl.CalculatorsListener, org.openxava.hibernate.impl.ReferenceConverterToDBListener"/>
        <property name="hibernate.ejb.event.pre-delete" value="org.openxava.hibernate.impl.CalculatorsListener"/>
        <property name="hibernate.ejb.event.post-load" value="org.openxava.hibernate.impl.CalculatorsListener"/>
        -->
    </properties>
</persistence-unit>
Also if you use XML components you no longer can have a reference used as key if the value does not exist in the referenced table. This case is no longer allowed by Hibernate. This case has never been supported in JPA. You should think in a different way of solving your issue, such as adding an autogenerated key or creating the corresponding row in the referenced table.
With Hibernate 4.3 the default way of releasing connections has changed, so you could find a "Could not open connection error". To avoid it add the next entry to your persistence.xml:
<persistence-unit name="default">
    ...
    <properties>
        ...
        <!-- Add the next entry -->
        <property name="hibernate.connection.release_mode" value="after_transaction"/>
 
    </properties>
 
</persistence-unit>

Hibernate Validator 3 dropped

Until now we have included both, the old Hibernate Validator 3 and the latest Hibernate Validator version in OpenXava distribution for maximum backward compatibility. Unfortunately Hibernate 4.3 does not support Hibernate Validator 3, so we have to remove it from OpenXava.
If you just use validation annotations as @Max, @Length, @Size, etc. it's enough to change the imports, change:
import org.hibernate.validator.*;
By:
import javax.validation.constraints.*;
import org.hibernate.validator.constraints.*;
In the case of @Digits apart of changing the above imports you have to change the parameter names, changing this:
@Digits(integerDigits=10, fractionalDigits=6)
By:
@Digits(integer=10, fraction=6)
You cannot longer use InvalidStateException of Hibernate Validator 3. Therefore, if you use it to throw a validation error from your entity or action you have to change it by other exception. For example, a code like this:
@PreRemove
public void validateOnRemove() {
    if (number == 1) {
        throw new InvalidStateException(
            new InvalidValue [] {
                new InvalidValue(
                    "one_not_deletable", getClass(), "number",
                    getNumber(), this)
            }
        );
    }
}
Now it could be written in this way:
@PreRemove
public void validateOnRemove() {
    if (number == 1) {
        throw new javax.validation.ValidationException("one_not_deletable");
    }
}
If you have defined your own validator with the Old Hibernate Validator you should rewrite it using the Bean Validation standard. Don't worry, converting it is very easy. In your annotation change @ValidatorClass by @Constraint and add groups() and payload(), thus:
@Constraint(validatedBy = MyValidator.class) // Instead of @ValidatorClass(PropertyValidatorValidator.class)
public @interface MyAnnotation {
 
    ...
 
    // Add the next code
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
 
}
And in the validator class change this:
public class RequiredValidator implements Validator<Required> {
By:
public class RequiredValidator implements ConstraintValidator<Required, Object> {
And this:
public boolean isValid(Object value) {
By:
public boolean isValid(Object value, ConstraintValidatorContext context) {
You can keep the rest of your code as is.

@Required, @PropertyValidator and @EntityValidator are Bean Validation restriction

Before, they were Hibernate Validator 3 restrictions. If you do your own commit and try to catch the validation exception you have to change the exception to catch. If you have a code like this:
try {
    XPersistence.commit();
}
catch (RollbackException ex) {
    if (ex.getCause() instanceof InvalidStateException) {
        InvalidStateException iex = (InvalidStateException) ex.getCause();
        int invalidValuesCount = iex.getInvalidValues().length;
        String property = iex.getInvalidValues()[0].getPropertyName();
        String message = iex.getInvalidValues()[0].getMessage();
        ...
    }
}
You should write it in this way:
try {
    XPersistence.commit();
}
catch (RollbackException ex) {
    if (ex.getCause() instanceof ConstraintViolationException) {
        ConstraintViolationException cex = (ConstraintViolationException) ex.getCause();
        int invalidValuesCount = cex.getConstraintViolations().size();
        ConstraintViolation v = cex.getConstraintViolations().iterator().next();
        String property = v.getPropertyPath().toString());
        String message = v.getMessage());
        ...
    }
}

Prefix for JNDI in older Tomcats

Hibernate 4.3 uses a different way for looking the JNDI resources that works fine with Tomcat 7.0.27 (and better) and Tomcat 6.0.36 (and better) but fails with previous versions. This is not a bug of Hibernate but a Tomcat bug. Fortunately, there is a trick to make the new Hibernate works even with older Tomcat versions, just add a // to the JNDI name. That is, if you're using a Tomcat version previous to 7.0.27 or 6.0.36 just change in your persistence.xml this:
<non-jta-data-source>java:comp/env/jdbc/YourApplicationDS</non-jta-data-source>
By this:
<non-jta-data-source>java://comp/env/jdbc/YourApplicationDS</non-jta-data-source>
And in hibernate.cfg.xml change this:
<property name="hibernate.connection.datasource">java:comp/env/jdbc/YourApplicationDS</property>
By this:
<property name="hibernate.connection.datasource">java://comp/env/jdbc/YourApplicationDS</property>
Note the // before comp. If you use JNDI names in other places you shoud change them too. The good thing is that newer Tomcat versions also work in this way, so if you use always this notation your application will work in any Tomcat.

EL libraries upgrade for Tomcat 6

If you're using Tomcat 6 copy el-api.jar and jasper-el.jar from the Tomcat lib folder included in OpenXava (or any Tomcat 7) to the lib folder of your Tomcat 6. This is required by the latest Hibernate Validator version.

Automated Business Logic (ABL) library dropped

Unfortunately, ABL does not support Hibernate 4.3. Moreover, ABL has been discontinued since 2012, so it will not support Hibernate 4.3 in the future. Therefore, we have not other option but removing ABL from OpenXava distribution. Fortunately, moving the logic in ABL annotations to Java code is easy. For example, if you have an ABL logic class like this:
public class OrderLogic {
 
    @Formula("productPrice * qtyOrdered")
    public void deriveAmount() { }
 
}
Remove the above class and move the calculation in @Formula annotation to a @PrePersist and @PreUpdate method in the entity, thus:
@Entity
public class Order {
 
    ...
 
    @PrePersist @PreUpdate
    private void deriveAmount() {
        amount = new BigDecimal(qtyOrdered).multiply(productPrice);
    }
}
Furthermore, you have to remove the next entry from your persistence.xml:
<property name="hibernate.current_session_context_class"
    value="com.autobizlogic.abl.session.LogicThreadLocalSessionContext"/>

schema.path required in generateSchema ant target

This affects to generateSchema not to updateSchema. If you have a generateSchema target in your build.xml, add schema.path, as following:
<!-- Generates the schema from scratch. Shows it in console, but does not execute it -->
<target name="generateSchema">
 
    <ant antfile="../OpenXava/build.xml" target="generateSchemaJPA">
        <property name="persistence.unit" value="junit"/>
        <!-- ADD THE NEXT LINE FOR V5.3 -->
        <property name="schema.path" value="../OpenXavaTest/lib/hsqldb.jar"/>
    </ant>
 
</target>

Migration from OpenXava 5.2 to OpenXava 5.2.1

Entity from View has nulls for non-existing references

Until v5.2 all references of the entity obtained via getView().getEntity() have value, even if the references do not exist. It was producing a very odd bug because JPA tries to save transient objects as references. Since v5.2.1, empty references are null, this is more natural (it works in the same way when you get the object from database) and it solves the above bug.
If you have code that relies in this behavior you must change it. That is, you have to make changes like the next one:
Invoice invoice = (Invoice) getView().getEntity();
if (invoice.getCustomer().getNumber() == 0) { // In v5.2 if customer is empty an empty customer is returned
By:
Invoice invoice = (Invoice) getView().getEntity();
if (invoice.getCustomer() == null) { // In v5.2.1 if customer is empty a null is returned

Migration from OpenXava 5.1.x to OpenXava 5.2

HtmlUnit upgraded to 2.15

If you use HtmlUnit directly from your jUnit test by means of getHtmlPage() or getWebClient() you should adapt your code to the new HtmlUnit 2.15 API. For example, you should change:
getWebClient().setCssEnabled(true);
By:
getWebClient().getOptions().setCssEnabled(true);
And:
HtmlElement console = getHtmlPage().getElementById("xava_console");
By:
HtmlElement console = getHtmlPage().getHtmlElementById("xava_console");
And many more things. Unfortunately, HtmlUnit team refactor their library in each new minor version, so HtmlUnit is never backward compatible.

Migration from OpenXava 5.0.x to OpenXava 5.1

@DefaultValueCalculator dependent on other properties changes its behavior

If you have a default calculator like this one:
@DefaultValueCalculator(
    value=UnitPriceCalculator.class,
    properties=@PropertyValue(
        name="productNumber",
        from="product.number")
)
private BigDecimal unitPrice;
With versions previous to 5.1 when product.number changes unitPrice is recalculated only if it has not value yet. Since version 5.1 unitPrice is recalculated always that product.number changes.
This new behavior is more natural, so if you do not change anything your user just will have a better behavior for his applications. Anyways, maybe you want that the value would be calculated only the first time, just like before. In this case you should rewrite your logic using @OnChage, that is you should change the above code by this:
@OnChange(OnChangeProductRecalculateUnitPriceAction.class)
private Product product;
 
private BigDecimal unitPrice;

Migration from OpenXava 4.9.1 to OpenXava 5.0

User login affects your jUnit tests

Now it's required that the user signs in before executing a module so your current jUnit tests will fail. To solve this disable the login mechanism adding the next entries to your naviox.properties file in properties folder:
autologinUser=admin
autologinPassword=admin
In this way your tests will run fine without recode them.
Another option is to leave the login mechanism active and to add the login logic in your test:
public void testMyTest() throws Exception {
    login("admin", "admin");
    ...
}

Executing standalone modules is no longer available by default

When you go to /MyApplication/modules/MyModule with your browser, the module is shown with menus and login included. This is not a problem at all, because the menus are very lightweight and login can be disable with autologinUser and autologinPassword in naviox.properties. Moreover, inside Liferay the modules work as usual.
But if for some reason you prefer to work in the old way you can deactivate login and menus and use the old visual style for your modules in OpenXava 5. To do it edit the web.xml file of OpenXava project and remove:
<filter>
    <filter-name>naviox</filter-name>
    <filter-class>com.openxava.naviox.web.NaviOXFilter</filter-class>
</filter>
 
<filter-mapping>
    <filter-name>naviox</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>
 
<filter-mapping>
    <filter-name>naviox</filter-name>
    <servlet-name>naviox</servlet-name>
</filter-mapping>
 
<filter-mapping>
    <filter-name>naviox</filter-name>
    <servlet-name>module</servlet-name>
</filter-mapping>
Also change:
<servlet>
    <servlet-name>naviox</servlet-name>
    <servlet-class>com.openxava.naviox.web.NaviOXServlet</servlet-class>
</servlet>
By:
<servlet>
    <servlet-name>modules</servlet-name>
    <servlet-class>org.openxava.web.servlets.ModuleServlet</servlet-class>
</servlet>
And change:
<servlet-mapping>
    <servlet-name>naviox</servlet-name>
    <url-pattern>/modules/*</url-pattern>
</servlet-mapping>
By:
<servlet-mapping>
    <servlet-name>modules</servlet-name>
    <url-pattern>/modules/*</url-pattern>
</servlet-mapping>
Finally remove:
<servlet-mapping>
    <servlet-name>naviox</servlet-name>
    <url-pattern>/m/*</url-pattern>
</servlet-mapping>
With the above changes in OpenXava/web.xml you have removed the menus and login. You must execute updateOX ant target to update the web.xml of your project.
For using the visual style of OpenXava 4 add the next entries to xava.properties of your project:
styleClass=org.openxava.web.style.Liferay51Style
styleCSS=liferay51/css/everything_unpacked.css

iPad native style is not used by default

When you access to an OpenXava 5 application from an iPad the style is the same of the desktop browser, the iPad native style is not shown by default. This is because iPad style only works with standalone modules, that OpenXava 5 does not use by default. If you want to use the native iPad style just follow the above instructions in section Executing standalone modules is no longer available by default to enable standalone modules.
About the support for iPad and tablets we're going to have an unique style that works fine in both desktop and tablet, a responsive style.

Transient classes require an explicit module declaration

For example, if you have a transient class called FilterByMonth with a controller called FilterByMonth and you try the URL /MyApplication/modules/FilterByMonth, it does not work until you declare it in application.xml as following:
<module name="FilterByMonth">
    <model name="FilterByMonth"/>
    <controller name="FilterByMonth"/>
</module>
Anyways, always it has been needed to declare the modules for transient classes in order to generate portlets, therefore if you work with portals you already have the modules defined.

FINEST log level produces a lot of trace

Until now FINEST log level produced a small amount of trace, but since v5.0 OpenXava generates a lot of trace with FINEST. Therefore you have to edit your xava.properties file and change:
javaLoggingLevel=FINEST
By:
javaLoggingLevel=FINE
If you want to keep a moderate amount of trace.
Until v4.9.1 the OpenXava projects created from OpenXavaTemplate had FINEST configured by default, since v5.0 they have FINE.

Objects class from org.openxava.util removed

This class conflicts with the java.util.Objects class of Java 7. Instead of qualifying the class everywhere we prefer to rename it to XObjects. In your code just replace Objects by XObjects, as following:
Objects.execute(myObject, "doSomething");
Instead now you have to write:
XObjects.execute(myObject, "doSomething");

AccessTracking removed from the distribution

You can continue using AccessTracking without any problem, just execute the updateOX ant target from AccessTracking after updating OpenXava.

URL used by ModuleTestBase includes a parameter by default

This only affects you if you overwrite getModuleURL() to add parameters. In that case just change ? by &:
public class MyModuleTest extends ModuleTestBase {
 
    ...
 
    @Override
    protected String getModuleURL() {
        // return super.getModuleURL() + "?myParameter=5"; // With ? in v4.x.x
        return super.getModuleURL() + "&myParameter=5"; // With & in v5.0
    }
}

@Digits annuls default scale

When @Digits is specified default scale is ignored even if fraction is not specified. It means that if you write:
@Digits(integer=10)
private BigDecimal amount;
With v4.x it had 2 fraction digits because default scale for BigDecimal is 2. However, since v5.0 it has 0 digits, because not specifying fraction is equals to write fraction=0. This allows you to have BigDecimal numbers with 0 for fraction part, but it could do than some of your existing numeric properties stop to use 2 fraction digits. To fix it, just specify fraction explicitly, thus:
@Digits(integer=10, fraction=2)
private BigDecimal amount;

BigDecimal formatting fixed (for jUnit tests)

Scale defined in default-size.xml and from @Column and @Digits was ignored when formatting. We fixed it. Yes, the number formatting works better, but you have to adapt your tests. For example, if you use a BigDecimal with no annotations you should change:
assertValue("myBigDecimalNumber", "20");
by this:
assertValue("myBigDecimalNumber", "20.00");

Migration from OpenXava 4.9 to OpenXava 4.9.1

Method getFrame() access modifier changed

The access modifier of the method getFrame() in org.openxava.web.style.Style was changed from protected to public. If you have classes which overrides getFrame(), then you are required to change its access modifier from protected to public.

Migration from OpenXava 4.8.1 to OpenXava 4.9

PDF report headers can use several lines

This does not affect your application code at all. However, if you verify the PDF content in your automatic tests maybe you need to make some adjustments. For example, the next code would fail if the header of the report now use 2 lines instead of 1:
assertPopupPDFLinesCount(5); // Maybe now there are 6 lines, because the header uses 2 lines

CustomReport controller renamed to MyReport

It's unlikely that you need to change your code at all, because this is a controller for internal use of 'My reports' dialog and available only since OpenXava 4.6. However, if you have used actions of CustomReport controller in your jUnit tests you have to rename them to MyReport.

Migration from OpenXava 4.8 to OpenXava 4.8.1

Hidding a member whose name is the same of its container section

We have fixed View.setHidden() to work with sections too, it already worked with groups but not with sections. Therefore, if you have a view like this one:
@View(members=
  ...
  "remarks { advice, shortcut; remarks }"
  ...
)
Where the remarks property is inside a remarks section. Until now if you write this:
getView().setHidden("remarks", true);
You hid the remarks property, however since OpenXava 4.8.1 you'll hide the remarks section. In this case, if you still want to hide the property and not the section you should rename the section, as following:
@View(members=
   ...
   "comment { advice, shortcut; remarks }"
   ...
)

Migration from OpenXava 4.7.1 to OpenXava 4.8

No issues.

Migration from OpenXava 4.7 to OpenXava 4.7.1

Gallery.return action renamed to Gallery.close

This is because Gallery editor now uses a dialog instead of a plain view. Moreover, the controller for read only Gallery is Close instead of Return. It's unlikely that you need to change your code at all. However, if you have used this action in jUnit tests you will need to rename it.

Migration from OpenXava 4.6.1 to OpenXava 4.7

Action ExtendedPrint.customReport renamed to ExtendedPrint.myReports

It's unlikely that you need to change your code at all, because this is an action from Typical (so always present) and available only since OpenXava 4.6. However, if you have used this action in jUnit tests, @Action or IChainAction, you will need to rename it.

Method getSelected() of Tab and TabBaseAction deprecated, now we will use getSelectedKeys()

The getSelected() method of Tab and TabBaseAction has been deprecated, instead we have getSelectedKeys(), this method return the keys (Map) from the selected elements.
In most cases getSelected() works well, but if there are some row out of the range of load rows it malfunctions. E.g.: first we select a row, afterwards we order by any column and then we leave this row out of the range of loaded rows. If we use getSelected() we don't get this row, but using getSelectedKeys() we do it.
We have to change in our code:
int[] selected = tab.getSelected();
for (int i = 0; i < selected.length; i++){
     Map key = (Map) tab.getTableModel().getObjectAt(selected[i]);
     ....
}
by:
Map[] selected = tab.getSelectedKeys();
for (int i = 0; i < selected.length; i++){
     Map key = selected[i];
     ....
}

Migration from OpenXava 4.6 to OpenXava 4.6.1

Messages in i18n files with no arguments are formatted in the standard way

Really this is a bug fix, but it can affect your i18n messages if they contain apostrophes, so you have to change:
my_message=It can't be in that way
by
my_message=It can''t be in that way
Note, you have to change ' by ''.

Migration from OpenXava 4.5.1 to OpenXava 4.6

No issues.

Migration from OpenXava 4.5 to OpenXava 4.5.1

Custom editors must specify tabindex attribute

In order to be in the correct tab order the editors must specify tabindex="1" in its HTML code, thus:
<input id="<%=propertyKey%>"
    name="<%=propertyKey%>" class="<%=style.getEditor()%> <%=numericClass%>"
    type="<%=inputType%>"
    tabindex="1" <!-- Now, you have put this-->
    ...
/>

Migration from OpenXava 4.4.x to OpenXava 4.5

Pure select in baseCondition of @Tab now must use JPQL syntax and not SQL

Since v4.5 OpenXava uses JPA to obtain tabular data, before it used SQL. It means that when you use baseCondition to write the complete select you have to use the JPQL syntax, SQL is no longer supported.
That is, if your select is like this one:
baseCondition =
    "select NUMBER, DESCRIPTION, FAMILY.DESCRIPTION " +
    "from   XAVATEST.SUBFAMILY, XAVATEST.FAMILY " +
    "where  SUBFAMILY.FAMILY = FAMILY.NUMBER"
You have to rewrite it in this way:
baseCondition =
    "select e.number, e.description, f.description " +
    "from Subfamily e, Family f " +
    "where e.familyNumber = f.number"
The syntax of JPQL and SQL is very alike, usually you will not need to do big changes other that using property and entity names intestad of column and table names. You have to use e as alias for the main entity.

The condition of @DescriptionsList now uses JPQL syntax and not SQL

Since v4.5 OpenXava uses JPA to obtain the data for the combos, so you have to use JPQL syntax in condition. If you use not too complicated conditions and use ${propertyName} instead of column name, surely you do not need to do any change. However, maybe you need to do some change, specially if you use column names. For example, the next code no longer work:
@DescriptionsList(
    // It does not works because THINGID is a column name, so JPA does not recognized it
    condition="${thing.number} = (SELECT THINGID FROM ${Thing} WHERE name = 'CAR')"
)
The solution is using property names instead of column names, in this case changing THINGID by number is enough to fix the problem:
@DescriptionsList(
    // It works because we use the property name, number, instead of THINGID
    condition="${thing.number} = (SELECT number FROM ${Thing} WHERE name = 'CAR')"
)
Another option is to write the complete sentence in pure JPQL, given that the ${} are no longer required, as following:
@DescriptionsList(
    // We can use a pure JPQL query without ${propertyName}
    condition="e.thing.number = (SELECT t.number FROM Thing t WHERE t.name = 'CAR')"
)
If you use JPQL you have to use e as alias for the main entity.

@OnSelectElementAction does not refresh by default its collection

This new behavior produces a much better performance in many cases, specially when you are working with huge collection and selecting an elements does not change the collection data. However, if you have a case when your @OnSelectElementAction changes the collection content you have to refresh the collections explicitly, as following:
public class MyOnSelectElementAction extends OnSelectElementBaseAction {
 
    public void execute() throws Exception {
        doSomethingThatModifiesTheCollection();
        getView().refreshCollections(); // Since v4.5 you have to add this line
    }
 
}

Migration from OpenXava 4.3.x to OpenXava 4.4

HtmlUnit upgraded from 2.5 to 2.9

HtmlUnit is the library used to simulate a browser from the jUnit tests. It has been upgraded to 2.9 version. HtmlUnit has renamed and dropped some methods and classes, indeed they are always refactoring their library (refactoring is good for applications but not so good for libraries). Probably you do not need to change anything in your jUnit tests because ModuleTestBase hides HtmlUnit, however if you are using the HtmlUnit API directly, using getHtmlPage() from ModuleTestBase for example, maybe you have to adapt some method calls.

Migration from OpenXava 4.2.x to OpenXava 4.3

No issues.

Migration from OpenXava 4.1.x to OpenXava 4.2

No issues.

Migration from OpenXava 4.0.1 to OpenXava 4.1

New action in list and collections (for junit tests)

The list and collections have a new action available for the users (List.sumColumn), therefore if you test for all present actions in your junit tests, you need to modify it in order to take into account the new List.sumColumn action:
private String [] listActions = {
"Mode.detailAndFirst",
"Mode.split",
"List.filter",
"List.customize",
"List.orderBy",
"List.viewDetail",
"List.hideRows",
"List.sumColumn" // ADD THIS ENTRY
};
assertActions(listActions);

Migration from OpenXava 4.0 to OpenXava 4.0.1

There is not default converter for boolean

From now on there is not a default converter defined in default-converters.xml for java.lang.Boolean and boolean. Really, this does not produce any incompatibility problem in JPA applications, since in these applications the JPA engine does the conversion itself. However, if you have a old XML application, you only have to regenerate the code and everything will work fine, because most database do a good job translating boolean to numeric automatically. Anyways, you can configure your application in order that it works as before, just add the following lines to the converters.xml file in the xava folder of your application:
<for-type type="boolean"
converter-class="org.openxava.converters.Boolean01Converter"
cmp-type="java.lang.Integer"/>
 
<for-type type="java.lang.Boolean"
converter-class="org.openxava.converters.Boolean01Converter"
cmp-type="java.lang.Integer"/>
Remember, adding these lines is rarely necessary, regenerating code must be enough. If you application is a JPA application (the usual case) you do not need to do anything.

Migration from OpenXava 4m6 to OpenXava 4.0

No issues.

Migration from OpenXava 4m5 to OpenXava 4m6

Hibernate updated to Hibernate 3.6

In OpenXava 4m6 the Hibernate engine has been upgraded to Hibernate 3.6 in order to support JPA 2.0. Most of the code works with no modification. However, there are some details maybe you have to modify in your code. Below you will find some of those details.
Additionally, it's hightly advisable that you undeploy your old application from the application server, and deploy it again. That is, delete the old application from webapps folder of Tomcat, before deploying a new version of your application based on OX4m6, thus you will be sure that the old JPA and Hibernate jars are removed. Also remove the .dist folders from your workspace or workspace.dist.

Nonexistent @ManyToOne references used as @Id are no longer supported (Hibernate 3.6)

Hibernate 3.6 does not support nonexistent @ManyToOne references used as @Id. That is, if you have an entity with the next ids:
public class Delivery {
 
@Id @Column(length=5)
private int number;
 
@Id @ManyToOne(fetch=FetchType.LAZY)
private DeliveryType type;  // The type must exist in the database always
...
}
The reference to DeliveryType must exist always in the database.
Really, this is a very rare case that you will only face when working against legacy databases designed by programmers of the pre-RDBMS era (like RPG programmers). They sometimes use composite keys that include references to other tables, and when the reference does not exist they put zeroes in the fields. If you face this case you can solve it in some of the next ways:

In order to assign an already existing entity to a reference it must be managed (Hibernate 3.6)

That is, in previous versions of Hibernate, you could write:
Delivery delivery = new Delivery();
DeliveryType deliveryType = new DeliveryType(); // We create a new DeliveryType,
// instead of searching it
deliveryType.setNumber(66); // The DeliveryType 66 already exist in database
delivery.setType(deliveryType);
...
XPersistence.getManager().persist(delivery);
But, this does not work with Hibernate 3.6, instead you have to write it in the next way:
Delivery delivery = new Delivery();
DeliveryType deliveryType = XPersistence.getManager()
.find(DeliveryType.class, 66); // We searh it
delivery.setType(deliveryType);
XPersistence.getManager().persist(delivery);

Entity with only one @ManyToOne reference as key (Hibernate 3.6)

With previous versions of Hibernate you could write the next code in your entity:
@Entity
@IdClass(CustomerContactPersonKey.class)
public class CustomerContactPerson {
 
@Id @ManyToOne(fetch=FetchType.LAZY)
private Customer customer;
 
// No more @Id fields
 
...
 
}
And the reference to it in this way:
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="CUSTOMERCONTACT") // With no referencedColumnName attribute
private CustomerContactPerson customerContactPerson;
And it worked fine. However, with Hibernate 3.6 this does not work. Fortunately, there is a way of achieving the same effect. Just write your entity in this way:
@Entity // @IdClass is no longer used
public class CustomerContactPerson
implements java.io.Serializable { // Must implement Serializable
 
@Id @ManyToOne(fetch=FetchType.LAZY)
private Customer customer;
 
// No more @Id fields
 
...
 
}
And the reference in this way:
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="CUSTOMERCONTACT",
referencedColumnName="CUSTOMER_NUMBER") // referencedColumnName is mandatory
})
private CustomerContactPerson customerContactPerson;

CharBooleanType Hibernate type does not work (Hibernate 3.6)

CharBooleanType type (and some other Hibernate types) has been deprecrated, even more, they do not work fine in Hibernate 3.6. If you have a type that extends from CharBooleanType, you must rewrite it extending AbstractSingleColumnStandardBasicType. See the SiNoType in org.openxava.types package.

Discriminator throws duplicate Id (Hibernate 3.6)

Entities used for table per class inheritance using discriminator which field is also an @Id, will throw a duplicate id error. Suppose that you have an entity description like this case:
@Entity
@Table(name = "`TABLES`")
@DiscriminatorColumn(name="ID",
discriminatorType=DiscriminatorType.STRING,
length=20)
 
This would work without problem in 3.4, but will complain in 3.6 (and I believe in 3.5 too). You have to use a Hibernate annotation @DiscriminatorOptions like this:
@Entity
@Table(name = "`TABLES`")
@DiscriminatorColumn(name="ID",
discriminatorType=DiscriminatorType.STRING,
length=20)
@DiscriminatorOptions(insert = false) // <-- Hibernate dependent annotation
 
And it will work.

Method getProperty() renamed in ModuleTestBase

Method getProperty() of ModuleTestBase has been renamed to getXavaJUnitProperty(). So, if you use it in your test you have to rename the method calls, as following:
String host = getProperty("host"); // Until v4m5
// Must be replace with
String host = getXavaJUnitProperty("host"); // Since v4m6
This change was needed to allow using Groovy to write JUnit tests.

Migration from OpenXava 4m4 to OpenXava 4m5

Navigation controller is not added automatically

Until now Navigation controller (with the previous - home - next actions in detail mode) was added automatically to all modules with detail and list. From now on, this controller is no longer added implicitly. This is not a problem since Typical extends it, but if you have a detail - list module with no Typical controller, then you have to add Navigation explicitly:
<module name="ChangeProductsPrice">
<model name="Product"/>
<controller name="Navigation"/>  <!-- You have to add this -->
<controller name="ChangeProductsPrice"/>
</module>

New split mode - jUnit changes

In addition to detail and list, now we have a new mode, split, that allows to show the list and the detail at the same time. This feature does not produce any incompatibility at application level, but if you use assertActions() in your tests maybe you have to add this new action:
String [] listActions = {
"Print.generatePdf",
"Print.generateExcel",
"CRUD.new",
"CRUD.deleteSelected",
"Mode.detailAndFirst",
"Mode.split", // YOU HAVE TO ADD THIS
"List.filter",
"List.customize",
"List.orderBy",
"List.viewDetail",
"List.hideRows",
};
assertActions(listActions);
If you do not like this new split mode, you can remove it from your aplication adding the next entry in xava.properties:
defaultModeController=DetailList
In this case the mode controller is not Mode but DetailList, this implies that you have to change your junit tests:
// execute("Mode.list"); // NO if defaultModeController=DetailList in xava.properties
execute("DetailList.list"); // OK if defaultModeController=DetailList in xava.properties

New CRUD.deleteRow action - jUnit changes

The CRUD.deleteSelected action has been split into CRUD.deleteSelected and CRUD.deleteRow. If you used CRUD.deleteSelected with row argument, you have to change it by CRUD.deleteRow:
// execute("CRUD.deleteSelected", "row=2"); // NO, since 4m5
execute("CRUD.deleteRow", "row=2"); // YES
Moreover, given that CRUD.deleteRow is available by default for all module, if you use assertActions() in your tests maybe you have to add it to the list of actions.

View is not editable by default

From now on when a module is initialized the View object is not editable. This is no big deal because the new and search actions set the correct editable state of the view. But if you have a custom new or search action maybe you have to modify them to set the editable state explicitly:
public class MySearchAction extends ViewBaseAction {
 
public void execute() throws Exception {
...
getView().setKeyEditable(false);  // You have to call setKeyEditable()
getView().setEditable(true);      // and setEditalbe() explicitly
...
}
 
}

Migration from OpenXava 4m3 to OpenXava 4m4

CRUD.search now uses a dialog - jUnit changes

The CRUD.search action now uses a dialog to entry the search data. This means that all your junit tests that uses CRUD.search will fail. That is, if you have a test like the next one:
setValue("number", "1");
execute("CRUD.search");
assertValue("description", "Number one");
It does not work now. You must rewrite it. To do it, you have 2 options. The first one is to adapt your test to the new CRUD.search action behavior:
execute("CRUD.search"); // It shows a dialog
setValue("number", "1");
execute("Search.search"); // It does the search and close the dialog
assertValue("description", "Number one");
The second option is changing "CRUD.search" by "CRUD.refresh", since the old CRUD.search has been renamed as CRUD.refresh:
setValue("number", "1");
execute("CRUD.refresh"); // Instead of CRUD.search
assertValue("description", "Number one");
Moreover, given that CRUD.refresh is available by default for all modules, if you use assertActions() in your tests maybe you have to add it to the list of actions.

Migration from OpenXava 4m2 to OpenXava 4m3

MapFacade.getValues() includes the model name in the result

MapFacade.getValues() now includes the model name in the result, with an entry with the key MapFacade.MODEL_NAME. If you use the standard OpenXava classes (such as View or PropertiesManager) everything will work fine, but if you have your custom code maybe it fails because this new unexpected entry. In this case you have to remove the entry from the values, in this way:
Map values = MapFacace.getValues("Person", key, members);
values.remove(MapFacade.MODEL_NAME); // Maybe you need this line

Classes.getSimpleName() method dropped

The method getSimpleName() from Classes has been removed. Use getSimpleName() from Class available from Java 5 instead.
Change this:
Classes.getSimpleName(theClass);
by this:
theClass.getSimpleName();

Migration from OpenXava 4m1 to OpenXava 4m2

Attributes show-dialog and hide-dialog dropped from <action/>

The declarative way to show a dialog of 4m1 has been replaced by a programmatic one in v4m2. The new way is more flexible and requires less code, though the real reason to make this change is that the declarative way requires that developer touches his controllers.xml any time an improvement or change is done in standard OX actions about dialogs. That is, with the declarative way many improvements in OX requires a lot of migration instructions for the developer in order to upgrade his application. With the new programmatic approach, the developer only has to upgrade its OX version and enjoy, without touching his application.
The bad news is that you have to rewrite your dialog code, now instead of marking your action with show-dialog and hide-dialog, you must use showDialog() and closeDialog() methods. Compare the new way with the old way for more details

Collections use dialogs to edit, view and add details - Actions changes

All actions that extends from CollectionBaseAction or CollectionElementViewBaseAction retain its original behavior, so you do not need to do any change in most of your collection actions. But, if you have some detail action that extends directly from ViewBaseAction maybe you have to change the way you access to the parent view. Remember that now you are inside a dialog:
public class MyCollectionDetailAction extends ViewBaseAction  {
 
public void execute() throws Exception {
...
getView().setValue("name", "Pepe"); // Now getView() is the dialog view
getPreviousView().setValue("name", "Pepe"); // getPreviousView() is the
// view has opened the dialog
closeDialog();
}
}
 
That is, maybe you have to change getView() by getPreviousView() in some of your action.

Collections use dialogs to edit, view and add details - jUnit changes

It does not affect to your application code, but given that the collection bevahior has changed, you have to adapt your junit tests.The main difference is that the user now uses a dialog to edit the detail line of the collection, so the rest of the actions and values of the main user interface are not available, just because a modal dialog is used.
Now the members of the detail view are in the root of the view, so you must remove the collection prefix when reference to a collection element member:
// details is the name of the collection
setValue("details.quantity", "6");  // Now WRONG! You have to remove 'details'
setValue("quantity", "6"); // CORRECT! Without collection name
Also the actions available on editing a collection element (so inside a dialog) do not use any argument:
execute("Collection.save", "viewObject=xava_view_section1_details"); // WRONG!
execute("Collection.save"); // CORRECT!
If you want to access to the actions or members of the main view, you have to close the dialog first:
execute("Invoice.editDetail", "row=1,viewObject=xava_view_section1_details");
assertValue("quantity", "234");
closeDialog(); // Needed before executing CRUD.save
execute("CRUD.save");
When you save the collection element the dialog is closed, so if you want to add another detail you have to open the dialog again:
execute("Collection.save"); // This closes the dialog
execute("Collection.new", // It's needed to call to 'new' again, to open the dialog
"viewObject=xava_view_section1_details");
In nested collections you have to change the value of viewObject argument of the row actions, again because now it inside of a dialog that is itself the root view:
execute("Collection.new",
"viewObject=xava_view_deliveryPlaces_receptionists"); // WRONG!
execute("Collection.new",
"viewObject=xava_view_receptionists"); // CORRECT! Only the last
// nested collection name
This does not only appies to viewObject but also to other references to a nested collection in action argument. See the next example:
// WRONG: Using "deliveryPlaces.receptionists", the full qualified name
setConditionValues("deliveryPlaces.receptionists", new String[] { "J"} );
execute("List.filter", "collection=deliveryPlaces.receptionists");
assertCollectionRowCount("deliveryPlaces.receptionists", 1);
assertValueInCollection("deliveryPlaces.receptionists", 0, 0, "JUAN");
 
// CORRECT: Using "receptionists", the simple name
setConditionValues("receptionists", new String[] { "J"} );
execute("List.filter", "collection=receptionists");
assertCollectionRowCount("receptionists", 1);
assertValueInCollection("receptionists", 0, 0, "JUAN");
In general, if your test fails try to remove the collection name as prefix from member name, action argument, etc.

Row action in collection of entities is by default view and not edit

You have not to change the application code, but only the test code:
// Only for collections of entities with no @AsEmbedded
execute("Collection.edit",
"row=0,viewObject=xava_view_customers"); // WRONG! 'edit' is not longer used
execute("Collection.view",
"row=0,viewObject=xava_view_customers"); // CORRECT! Now 'view' action is used
This also implies that the view for element has not editable the key properties and has no delete action. Maybe you have to adapt your test:
// Inside the dialog that displays the collection element
assertEditable("number"); // WRONG! Key fields are not editable
execute("Collection.remove"); // WRONG! 'remove' action are not available
This change does not apply to collection with @AsEmbeddable, CascadeType.REMOVE or CascadeType.ALL.

Migration from OpenXava 3.1.4 to OpenXava 4m1

BaseAction implements IModuleContextAction

BaseAction now implements IModuleContextAction, so if some of your actions implement it you have to rewrite the setContext() method using super.setContext(). In this way:
public class MyAction extends BaseAction implements IModuleContextAction {
public void setContext(ModuleContext context) {
super.setContext(context);  // You must add this line
this.context = context;
}
}
Another option is to remove the implements IModuleContextAction and the setContext() method, and to use getContext(), protected method from BaseAction to access to the context.

The xava_currentReferenceLabel session object removed

Note: This change is not needed if you update directly to 4m2 or better, because since 4m2 injecting using <use-object /> in a non-existing property does not fail, but only produces a simple warning.
The xava_currentReferenceLabel session object is not longer used; so it has been removed from default-controllers.xml. This object was used by reference search actions, so if you have your custom search action you have to remove the reference to xava_currentReferenceLabel in your controllers.xml, just as shown the next code:
<controller name="MyReference">
<action name="search" hidden="true"
show-dialog="true"
class="org.openxava.test.actions.MySearchAction"
image="images/search.gif">
<use-object name="xava_view"/>
<use-object name="xava_referenceSubview"/>
<!-- This line must be removed
<use-object name="xava_currentReferenceLabel"/>
-->
<use-object name="xava_tab"/>
</action>
</controller>
Also it's convenient for search actions and other reference actions to use show-dialog="true" (show-dialog has been dropped in v4m2) in order to show the searching in a dialog, such as the standard OX search actions.

Migration from OpenXava 3.1.3 to OpenXava 3.1.4

AccessTracking table schema changed

In the AccessTracking project the schema of the table for access record has changed:
You have to change your current table if you want to update to the AccessTracking 3.1.4
This change is for working in databases with no support for USER as column name.

Migration from OpenXava 3.1.1 to OpenXava 3.1.2/3.1.3

No issues.

Migration from OpenXava 3.1 to OpenXava 3.1.1

HTML elements id generation changed for support multimodule page support

In order to support several module in the same portal page; OX, since v3.1.1, changes the way the HTML ids are generated. This has no effect in our application code since direct manipulation of HTML elements is rare in a typical OpenXava application. However, we need to do some little change in our junit tests.
When you use xava.keyProperty as argument in an action inside a junit test, you will not use xava.ModelName as prefix anymore. That is you have to change:
execute("Delivery.generateNumber", "xava.keyProperty=xava.Delivery.number");
by
execute("Delivery.generateNumber", "xava.keyProperty=number");
Just deleting xava.Delivery in this case.
To avoid a laborious migration OpenXava still support the old style for all actions of Reference controller.
Also if you inspect directly the HTML document using the ids, you have to decorate the ids with the decorateId() method. That is, if you have something as this:
HtmlImage image = (HtmlImage)
page.getHtmlElementsByName("xava.Formula.ingredients.image").get(0);
You need to change by the next code:
HtmlImage image = (HtmlImage)
page.getHtmlElementsByName(decorateId("ingredients.image")).get(0);
You use here decorateId(). Also note the you have to remove the prefix xava.Formula.

Migration from OpenXava 3.0.3 to OpenXava 3.1

JavaScript code of editors must be moved from JSPs to custom-editors.js

If some of your custom editors define JavaScript functions inside the JSP, you have to move them to a file with name custom-editors.js (maybe you need to create it) in the web/xava/js folder of your project. Note: Since v4m3 you can put the JavaScript code for the editors in any file, the name does not matter, in the folder web/xava/editors/js. In this way you can have one or more files for each editor, and easily to include third party libraries.
That is, if you have an editor called googleMapEditor.jsp with a JavaScript function called showMap(), just in this way:
<script>
function showMap(v) {
...
}
</script>
 
<!-- JSP code here -->
You have to move it to custom-editors.js, in this way:
if (openxava == null) var openxava = {};
if (openxava.editors == null) openxava.editors = {};
 
// googleMapEditor
if (openxava.editors.googleMap == null) openxava.editors.googleMap = {};
openxava.editors.googleMap.showMap = function(v){
...
}
 
And now inside your editor instead of calling to the function in this way:
<input ... onclick="showMap(value)"/>
you have to do it qualifiying the function:
<input ... onclick="openxava.editors.googleMap.showMap(value)"/>

Call to method View.refreshCollections() when collection data are modified

Since OpenXava 3.1 only modified data in the view are refreshed. When the user click on an action of a collection the collection is automatically refreshed, but if your action is outside of the collection then there is no way to know that the collection data have been modified. In this case you need to call explicitly to View.refreshCollections(). For example:
// It's not a collection action
public class TranslateAllCarrierNameAction extends ViewBaseAction {
 
public void execute() throws Exception {
for (Iterator it=Carrier.findAll().iterator(); it.hasNext(); ) {
Carrier c = (Carrier) it.next();
c.translate(); // Carrier is modified,
// these data are show currently in a collection of the view
}
getView().refreshCollections(); // To refresh the data of the
// displayed collections
}
 
}
That is, maybe you need to add getView().refreshCollections() if the collection data are not refreshed after executing your action.

More libraries needed in MANIFEST.MF (only for EJB2)

Edit the file build/ejb/META-INF/MANIFEST.MF, and add the next files ./lib/slf4j-api.jar ./lib/slf4j-jdk14.jar ./lib/javassist.jar to the jar list.
This only applied if you are using EJB (generating an EAR). Look at OpenXavaTest/build/ejb/META-INF/MANIFEST.MF for a complete and up-to-date list of jars.

Migration from OpenXava 3.0.2 to OpenXava 3.0.3

HttpUnit replaced by HtmlUnit for junit tests using ModuleTestBase

HttpUnit has been replaced by HtmlUnit for junit tests based on ModuleTestBase. The main reason for this is the lack of AJAX support from HttpUnit.
Most of your current junit test based on ModuleTestBase will continue working without touching them. HtmlUnit works as a real browser, allows you to do better testing, but there are some little changes that maybe you need to do to your test in some special cases.
These are the changes in ModuleTestBase:

Exact arguments for execute() are required

That is, if you write in your test:
execute("Reference.search", "keyProperty=xava.Carrier.warehouse.zoneNumber");
and the link in the page has keyProperty=xava.Carrier.warehouse.number, that is, it's not exactly equal; in the case of the HttpUnit it works, but in the case of the HtmlUnit it does not work. You cannot execute actions that are not available to the users by means of links or buttons, moreover your test must execute the action exactly in the same way that the user do it.

The methods allowDuplicateSubmit() and click() has been removed

Until now, when you want to simulate an user click you needed a code like this:
allowDuplicateSubmit();
click("MyController.myAction");
Calling to allowDuplicateSubmit() is mandatory before to use click(). The click() method throw the events associated to the button or link but does not work well in many cases. From now on, using HtmlUnit, the execute() just simulates a click(), and does it well, so click() and allowDuplicateSubmit() are no longer needed. If you have a code as the above one, you can replace it for something as this:


execute("MyController.myAction");

Method getForm() returns a HtmlForm

The protected method getForm() of ModuleTestBase that before returned a WebForm of HttpUnit now returns a HtmlForm of HtmlUnit. If you are using it in some test you must rewrite your test. Fortunately this method is rarely used.


Method getConversation() replaced by getWebClient()

The protected method getConversation() of ModuleTestBase that before returned a WebConversation() of HttpUnit has been replaced by getWebClient() method of HtmlUnit that retuns a WebClient. If you are using it in some test you must rewrite your test. Fortunately this method is rarely used.


Easier use of setConditionValue

Before you must write the next code:


String [] condition = { " ", "", "", "V" };
setConditionValues(condition);
When you want to fill the 4th element and the 2nd one was a combo (an enum or boolean). Note that you need to put a blankspace in the first one, really in all before the combo. This tricky, needed because of HttpUnit, is no longer needed. Now you can write this:


String [] condition = { "", "", "", "V" };
setConditionValues(cndition);
Without bother about blankspaces. Though spaces are still allowed.


Migration from OpenXava 3.0.1 to OpenXava 3.0.2

Object not found message includes search key values (for junit tests)

This can requires some slight changes in your junit tests. You must change a code as this in your test:


assertError("Object of type Invoice does not exists with that key");
by


assertError("Object of type Invoice does not exists with key Year:2008, Number:1");

Hibernate for user preferences is not longer used

Now Java Preferences are used for storing user preferences. OpenXavaDS and openxava-db are no longer needed.
So you must remove TabUserPreferences.hbm.xml and openxava-hibernate.cfg.xml from the persistence folder of your project.


Migration from OpenXava 3.0 to OpenXava 3.0.1

Validation annotations now are Hibernate Validator constraints

@Required, @PropertyValidator and @EntityValidator are defined since 3.0.1 as Hibernate Validator contrains. This means that when you save using directly JPA api, these validations are enforced.
That is, if you have an entity as this one:


@Entity
public class Customer {
 
@Required
private int number;
 
@Required
private String name;
 
@Required
private String remarks;
 
...
}
And you run the next code:


Customer c = new Customer();
c.setNumber(1);
c.setName("JUANITO");
// We left remarks property empty
XPersistence.getManager().save(c);
XPersistence.commit();
The code works with OX3.0, but fails with OX3.0.1, because in OX3.0.1 the @Required constraint is enforced when you save using JPA. In OX3.0, and older, validation was applied only when you save using OpenXava (con MapFacade, or OX standard action).
To fix this case, for example, you need to fill the remarks property before save.


Slight improvement in CRUD action 'new'

Now the new action automatically actives the initial section. This can break some junit tests. For example, if you have this code:


execute("Sections.change", "activeSection=2");
...
execute("CRUD.new");
setValue("propertyInSection2", "the value"); // This property is in section 2
In this case you have to return to the section 2 explicitly:


execute("Sections.change", "activeSection=2");
...
execute("CRUD.new");
// You must add the next line, because after 'new' we are in section 0
execute("Sections.change", "activeSection=2");
setValue("propertyInSection2", "the value"); // This property is in section 2

Migration from OpenXava 2.2.5 to OpenXava 3.0

Default persistence provider is JPA

Since v3.0 OpenXava uses JPA by default for persistence. If you want to continue using Hibernate as persistence provider in your application just put the next line in the xava.properties file of your project:


persistenceProviderClass=org.openxava.model.impl.HibernatePersistenceProvider

MapFacade does not longer throw RemoteException

Now the methods of MapFacade do not throw RemoteException but SystemException, that is a runtime exception.
This has little repercussion on your code, but if you have a code like this:


try {
MapFacade.validate("Invoice", values);
}
catch (RemoteException ex) {
...
}
 
Then you must change the RemoteException by a SystemException:


try {
MapFacade.validate("Invoice", values);
}
catch (SystemException ex) {
...
}
 
Moreover, XavaException is now a runtime exception. But this does not requires any change in your code.


Migration from OpenXava 2.2.4 to OpenXava 2.2.5

MapFacade is not autocommit from now on

Until now, when you write:


MapFacade.create("Customer", customerValues);
MapFacade.create("Invoice", invoiceValues);
These two lines were two transaction. If the invoice creation fails the customer was saved. That is, MapFacade had an autocommit police.
From now on MapFacade is not autocommit by default, that is, the above case will have only a transaction, commited by OX at the end of the action or test. Now, if fails invoice creation customer creation will not be done.
This can change slightly the behaviour of your actions in case of fails, but only if your actions do several call to MapFacade. If you want to preserver the old behaviour you have two options.
First option: add the next line to your properties/xava.properties file:


mapFacadeAutoCommit=true
Second option: commit the transaction manually. For example, the above code can be write in this way:


MapFacade.create("Customer", customerValues);
MapFacade.commit();
MapFacade.create("Invoice", invoiceValues);
MapFacade.commit();

Migration from OpenXava 2.2.3 to OpenXava 2.2.4

Schema for the images table of IMAGES_GALLERY stereotype

Now the schema for the images table is specified specified separately, that is, before you write this in your configuration properties file:


images.table=XAVATEST.IMAGES
Now you write this instead:


images.schema=XAVATEST

images.table=IMAGES

Migration from OpenXava 2.2.2 to OpenXava 2.2.3

Labels of list mode and collections are qualified (for junit tests)

Labels for list mode and collection now are qualified, that is if you have a property customer.name, before the label was Name, and now is Name of Customer. This can be affect some of your junit test, that is, if you have:


assertLabelInList(2, "Name"); // for customer.name
now must write:


assertLabelInList(2, "Name of Customer"); // for customer.name

AccessTracking table schema changed

In the AccessTracking project the schema of the table for access record has changed:


You have to change your current table if you want to update to the AccessTracking 2.2.3
This change is for working in databases with no support for TABLE, DATE and TIME as column names.

Migration from OpenXava 2.2.1 to OpenXava 2.2.2

No issues.

Migration from OpenXava 2.2 to OpenXava 2.2.1

MoneyFormatter (for jUnit tests)

A money formatter is applied by default for format/parser all values of stereotype MONEY, now all money data is always displayed with 2 decimal digits. Therefore you will need to adapt your junit test changing lines as this one:
assertValue("amount", "20");
by this one:
assertValue("amount", "20.00");
Or, if your prefer the old formatting style you can deactivate the formatter or use another editing your editors.xml file.

Action 'Mode.list" not available when the user navigate to another view (for junit tests)

When the user navigates to another view (for example to create or modify a reference) the link for go to list mode is not present now. Maybe you need to change your junit test.
For example in this junit code:


execute("Reference.createNew", "model=Family2,keyProperty=xava.Product2.family.number");
assertAction("Mode.list"); // Since 2.2.1 it fails
The assertAction("Mode.list") has to be removed.


Migration from OpenXava 2.1.5 to OpenXava 2.2

Default behaviour for collection of entities changes

Now, when user click on 'Add' in a collection the entities, he goes to a list where he can choose some entities to add. This may cause that your current JUnit test fails. You need to do a simple modification; simply change code like this in your JUnit test:


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);
by this one:


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);
Moreover, now the user can add several entities at once, thus a code as this:


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);
can be done in this way:


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);

Default behaviour for collection of aggregates changes

Now, when a detail of a collection is saved, the view of the detail is not hidden, this may cause that your current JUnit test fails. You need to do a simple modification; simply change code like this in your JUnit test:


execute("Collection.save", "viewObject=xava_view_section1_details");
execute("Collection.new", "viewObject=xava_view_section1_details"); // To remove
by this one:


execute("Collection.save", "viewObject=xava_view_section1_details");
That is, remove the "Collection.new" call, because after save the detail, the "new" action is automatically executed, thus the user interface is ready to enter a new detail.


Migration from OpenXava 2.1.4 to OpenXava 2.1.5

No issues.


Migration from OpenXava 2.1.3 to OpenXava 2.1.4

New actions in collections (for junit tests)

The collections have some new actions available for the users, therefore if you test for all presents actions in your junit tests, you need to modify it in order to take in account the new actions.
That is, if you have something as this in your junit test code:
String [] actions = {
"Navigation.previous",
"Navigation.first",
"Navigation.next",
"CRUD.new",
"CRUD.save",
"CRUD.delete",
"CRUD.search",
"Collection.new",
"Collection.removeSelected"
};
 
assertActions(actions);
you must change it by:
String [] actions = {
"Navigation.previous",
"Navigation.first",
"Navigation.next",
"CRUD.new",
"CRUD.save",
"CRUD.delete",
"CRUD.search",
"Collection.new",
"Collection.removeSelected",
"List.filter",        // New
"List.orderBy",       // New
"List.customize",     // New
"List.hideRows",      // New
"Print.generatePdf",  // New
"Print.generateExcel" // New
};
 
assertActions(actions);

Ant target generarPortlets removed

The ant target generarPorltets has been removed from OpenXava/build.xml because now it's exactly equal to generatePortlets. Therefore, if you have in your build.xml something like this:


<target name="generarPortlets">
<ant antfile="../OpenXava/build.xml" target="generarPortlets"/>
</target>
Must change it by:


<target name="generarPortlets">
<ant antfile="../OpenXava/build.xml" target="generatePortlets"/>
</target>

Migration from OpenXava 2.1 to OpenXava 2.1.3

JUnit test and key without value parsed as zero

Since 2.1.3 if a key property of type int, long or short has no value in the 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. For example if you have in a test case:



public void testSomething() throws Exception {
assertValue("number", "");
execute("MyControllers.myAction"); // This does not change number value
assertValue("number", "0"); // because OX parse empty string as 0 (until 2.1.2)
...
}
 
You now have to write in this way:


public void testSomething() throws Exception {
assertValue("number", "");
execute("MyControllers.myAction"); // This does not change number value
assertValue("number", ""); // because now (since 2.1.3) OX parse empty string as null
...
}
 

Migration from OpenXava 2.0.4 to OpenXava 2.1

WebSphere projects

If you deploy your projects in WebSphere you need to do the next little changes:
First, in the file hibernate/hibernate.cfg.xml of you project add the next blue marked code:


<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>
Second, in your configuration file for websphere (for example websphere-as400.properties) you have to add:


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>

Other changes that requires some migration

Migration from OpenXava 2.0.3 to OpenXava 2.0.4

Parse of numeric values

Now data values of type Number (Integer, BigDecimal, Short, etc) and Boolean (not boolean) are parsed as null if in the User Interface are in blank. Before numeric blank field was parsed as 0. This change does not produce big incompatibility problems because default-converters.xml defines the real conversion before to store in database (the real important matter). That is, this change affects only displaying. You incompatibility issues maybe the next one:


API changes

Migration from OpenXava 2.0.2 to OpenXava 2.0.3

No events on-change when searching are thrown

OpenXava Reference Guide (in the section 7.5) says that CRUD.searchByViewKey does not throw any on-change event, and CRUD.searchExecutingOnChange throw all on-change events. But because of a bug in ox2.0.2 (and previous) the CRUD.searchByViewKey threw on-change events of keys in the references, and CRUD.searchExecutingOnChange does not threw CRUD.searchExecutingOnChange of key in the references. This issue is fixed, therefore if your code rely in this erroneus behaviour you will need to adapt it.


Setting value for references (in combos) with compose key in JUnit tests

Setting value for references (in combos) with compose key in JUnit tests must be done using POJOs, now the use of EJB2 primary key is not supported.
See documentation in Migration from OpenXava 1.2.1 to OpenXava 2 below.


Migration from OpenXava 2.0.1 to OpenXava 2.0.2

Action Collection.hiddenDetail has been renamed to Collection.hideDetail in controllers.xml. You have to rename the action inside your junit tests.


Migration from OpenXava 2.0 to OpenXava 2.0.1

No issues.


Migration from OpenXava 1.2.1 to OpenXava 2

Setting value for references (in combos) with compose key in JUnit tests

So far, to set the value to a reference displayed as description-list (as combo), and mapped in database using multiple columns, you write:


DrivingLicenceKey key = new DrivingLicenceKey();
key.setType("C ");
key.setLevel(1);
setValue("drivingLicence.KEY", key.toString());
 
But, if you uses a pure POJOs version, without Key classes, you have to write:


DrivingLicence key = new DrivingLicence();
key.setType("C ");
key.setLevel(1);
setValue("drivingLicence.KEY", key.toString());
 
It's better to use the last way, because it's valid for POJOs and EJBs.


Hibernate: References with not null columns as foreign key

In EJB version if you have a reference to another entity that has primitive types as key, the code is generated in a way that no null is saved to database, even if you assign null to your reference.
In hibernate version if you assign null to the reference, null values are saved in database.
Of course, the behaviour of hibernate version is more correct, but you can in hibernate avoid null in database just using a converter in the reference mapping (see section 6.3 of Reference Guide).
That is, maybe you need to add some converters to your references in order to migrate your application from EJB2 to Hibernate.


Changing the active section

xava_activeSection is not longer used for changing the active section. Now if you want to change the active section you must to call to method setActiveSection of the desired view (org.openxava.view.View).


IAggragetOidCalculator

The setContainerKey method is renamed to setContainer. And its semantic changes too. Now the container object is received instead of the key. In this way this calculator is consistent in EJB2 and POJO (without key classes) versions.


Migration from OpenXava 1.2 to OpenXava 1.2.1

Hibernate generation

Now when the EJB code generation is done, the hibernate code generation is executed too (although the hibernate version still does not work at 100%).
Although you use only EJB version, you have to make this little adaptation in your project:


The hibernate.cfg.xml have to be:


<!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>
In addition you have to include the hibernate.dialect property in your configuration files:


hibernate.dialect=org.hibernate.dialect.HSQLDialect

XML OpenXava syntax

Migration from OpenXava 1.1 to OpenXava 1.2

Generated code

Now EJB remote interface has the suffix Remote, and the business interface generated for each component (for example ICustomer) has no all methods of the remote interface.
This is for allowing to the future version 2 of OpenXava work with EJB and Hibernate in the same project and at same time.
In order to adapt you code to this, you must:
For correct syntax error you can change code in this way:
Customer customer = CustomerUtil.getHome().findByName("PEPE");
String name = customer.getName();
By this:
ICustomer customer = CustomerUtil.getHome().findByName("PEPE");
String name = customer.getName();
If you use specific EJB methods then you need cast to remote interface:
Customer customer = CustomerUtil.getHome().findByName("PEPE");
CustomerKey key = customer.getPrimaryKey();
By this:
CustomerRemote customer = CustomerUtil.getHome().findByName("PEPE");
CustomerKey key = customer.getPrimaryKey();
That is, change Customer by ICustomer when possible, if not possible change Customer by CustomerRemote.

JUnit tests

Others

Migration from OpenXava 1.0 to OpenXava 1.1

APIs

JUnit tests


CustomReport