Edit the pom.xml file in your project and change the value of the openxava.version property to point to the latest OpenXava version, thus:
<properties>
<openxava.version>7.0.6</openxava.version>
...
</properties>
Rebuild your project:
We noticed that labels in list and collection when are translated to English, they can be understandable, but could be better. For this, we changed the order of the words and this affect JUnit code that use method like assertValue(), assertLabelInList(), assertValueInCollection(), and more that used to verify labels. For example, if you have something like this:
assertLabelInList(0, "Year of invoice");
Change it by:
assertLabelInList(0, "Invoice year");
If labels were before:
customer.address = Address of customer
customer.address.street = Street of address of customer
customer.address.street.number = Number of street of address of customer
Now they are:
customer.address = Customer address
customer.address.street = Customer address street
customer.address.street.number = Customer address street number
We fixed a bug about that scale=0 for @Column does not work, and given that when scale is not defined its default value is 0, now @Column(length=x) has scale=0 as default value instead of the scale=2. That is, you have to change this code:
@Column(length=6)
BigDecimal factor;
By this one:
@Column(length=6, scale=2) // ADD scale=2
BigDecimal factor;
If you do not define length or precision the value of scale is still 2, as always, so if you have:
@Column(column="FCTR")// scale is 2 by default, as always
BigDecimal factor;
You don't need to change anything. Moreover, if @Column annotation is missing altogether scale is still 2, as always.
To solve a bug, the combos for references as @DescriptionsList in filter part of list and collections no longer use the key, but the value of the field. This is something internal, it does not affect the application behavior. But it's possible you have to adapt some code. If you have a code like this in an action:
getTab().setConditionValue("seller.name", 1);
Change it by:
getTab().setConditionValue("seller.name", "JOHN SMITH");
Note as now for seller.name we use the actual seller name, not the id. We did it to fix a bug, but as a lateral effect now it's more natural and moreover it works in the same way of a reference with no @DescriptionsList, so adding or removing a @DescriptionsList to your reference does not affect the code of your actions.
Also you have to adapt your JUnit code that set value to list filter if a reference with @DescriptionsList is used. That is, change:
setConditionValues("", "1");
setConditionValues("", "CAR");
Here you're changing the id by the description or the name. Do the same for the JUnit code that verify the combo content. Change:
String [][] validValues = {
{ "", "" },
{ "2:_:LAMPPOST", "LAMPPOST" },
{ "0:_:HOUSE", "HOUSE" },
{ "3:_:DOOR", "DOOR" },
{ "1:_:CAR", "CAR" }
};
assertValidValues("conditionValue___3", validValues);
By:
String [][] validValues = {
{ "", "" },
{ "LAMPPOST", "LAMPPOST" },
{ "HOUSE", "HOUSE" },
{ "DOOR", "DOOR" },
{ "CAR", "CAR" }
};
assertValidValues("descriptionsListValue", validValues);
Note that we have removed the prefix id:_: for the key part of the map. Now, key and value have the same value.
OpenXava 7 is Maven compatible, so the classic structure of an OpenXava project is no longer recognized. You have to turn your project into a standard Maven project. Fortunately, all your current code is valid, only that it have to be placed in different folders. If you're not familiar with Maven, look at the standard directory layout of a Maven project.
The easier way to migrate to Maven is creating a new project using OpenXava 7.0, and then copying the source code and resources from your current project to the new one. So, first create a new OpenXava project using Openxava Studio 7, for that you can follow the instructions in Getting started guide.
The next step is to copy all your source code and resources from the old project to the corresponding folder in the new project, as following:
The test code is in a different folder in Maven, so you should copy:
The above is enough for most applications.
Also copy:
The servlets.xml, filters.xml and listeners.xml files are no longer supported. You can copy their content to the web.xml, that now is empty and ready for your own things, in src/main/webapp/WEB-INF. If you use @WebServlet, @WebFilter and @WebListener annotations you don't need to do any change.
If you use an extra third party library in your application you have to add a dependency in the pom.xml file in the root of your project. You no longer are going to copy jars in web/WEB/lib. If you're not familiar with Maven read about Maven dependecy mechanism.
If you use a database other than HSQLDB you have to add the dependency for your JDBC driver. For example, if you use MySQL add the next entry to your pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
For other database just ask Google, something like "maven dependency oracle" for example. In order your JDBC driver will be downloaded and included in your project you have to execute "mvn package" in your project. You can do it from command line (if you have Maven installed in your machine) or from OpenXava Studio (not needed to have Maven installed), with Run As > Maven Build... in your project and typing "package" as goal. This step is not needed if you use HSQLDB as database.
Now you can run your application. Put your mouse on src/main/java of your project and choose Run As > Java Application. From now on, you can modify your code and relaunch your application as always, even if you launch it in debug mode you can modify the code and see the result without relaunch the application. That it, you can work in development as you're used to do.
We no longer use Ant. Now you do everything using Maven commands. If you're not familiar with Maven read some Maven introduction documentation. For example, to create the war for deploying in production you use "mvn package", and get the war ready to be deployed in Tomcat in the target folder of your project. You can run all maven commands from OpenXava Studio, with the option Run As on your project.
Note that when you created the project with OpenXava the project name is in lowercase, this is because the nomenclature for Maven is to use lowercase for the name of artifactId, that matches with project name and deliverable (the generated war). For new projects you should user lowercase for project name. However, for years we have promoted first uppercase letter for project name in documentation, so probably you have your old project with its name starting with uppercase. You can choose migrating to lowercase and adopt the Maven standard way, but keep in mind that it would change the browser URL used by your users.<artifactId>accounting</artifactId>
<artifactId>Accounting</artifactId>
<finalName>accounting</finalName>
<finalName>Accounting</finalName>
<application name="accounting">
<application name="Accounting">
AppServer.run("accounting");
AppServer.run("Accounting");
We have done a hard work to adapt OpenXava in order it works nicely with Hibernate 5.6. However, you can find problems in your own JPA/Hibernate code. If you use JPA API everything should work as it, but there are new bugs in Hibernate 5.6 that can cause your current code to fail. We found some of them.
With Hibernate 5.3 when you use a property of a reference and this reference is part of the key, you don't need to add an explicit join in the query. This is in this way no matter the deep level. In Hibernate 5.6, you don't need to add the join if you have only one level of reference, but if you have a second level, you have to add it, if the second level has a composite key.
Saying it with code. If you have:
@Entity
public class TransportCharge {
@Id @ManyToOne
private Delivery delivery;
...
}
@Entity
public class Delivery {
@Id
private int number;
@Id @ManyToOne
private Invoice invoice;
...
}
@Entity
public class Invoice {
@Id
private int year;
@Id
private int number;
...
}
With the above code the next query run nicely with Hibernate 5.3:
String queryString="from TransportCharge o where o.delivery.invoice.year = :delivery_invoice_year";
Query query = XPersistence.getManager().createQuery(queryString);
query.setParameter("delivery_invoice_year", 2022);
But it fails with Hibernate 5.6. Curiously if you do the query against Delivery asking by invoice.year it works, it only fails with 2 levels or more. Moreover, if Invoice would have a single key, instead of a composite one, it works too. Hibernate 5.6 fails when you combine more than one level with composite keys.
Don't worry, the solution is easy, just add an explicit join for the first reference. That it, in the next way it works with Hibernate 5.6:
String queryString="from TransportCharge o join fetch o.delivery d where d.invoice.year = :delivery_invoice_year";
Query query = XPersistence.getManager().createQuery(queryString);
query.setParameter("delivery_invoice_year", 2022);
The solution is the join fetch o.delivery d. Conclusion, if some query fails for you with Hibernate 5.6 try to add an explicit join to your reference.
A new bug of Hibernate 5.6 is that it no longer recognizes javax.persistence.create-database-schemas, so if you have the next configuration in your persistence.xml:
<persistence-unit name="default">
...
<properties>
<property name="javax.persistence.schema-generation.database.action" value="update"/>
<property name="javax.persistence.create-database-schemas" value="true"/>
<property name="hibernate.default_schema" value="MYSCHEMA"/>
</properties>
</persistence-unit>
With Hibernate 5.3 it created the MYSCHEMA schema and then the tables inside, however with Hibernate 5.6 the MYSCHEMA schema is not created, hence the tables are not create neither. The solution is to create the MYSCHEMA schema by hand. You have to connect to your database with your database explorer and execute a CREATE SCHEMA MYSCHEMA (or equivalent) sentence. After it, you can start the application and the tables will be created.
XHibernate utility class has been removed because it was used in XML components applications, in JPA applications we use XPersistence instead, and we have removed XML components support in v7.0. Hibernate API is still available. In the rare case you use XHibernate in some point of your code, change:
Session session = XHibernate.getSession();
session.save(customer);
By:
Session session = (Session) XPersistence.getManager().getDelegate();
session.save(customer);
That is, you can get a Hibernate Session object from the JPA manager. Another alternative would be to get the Hibernate session directly in the Hibernate way, but in this case you have to create the SessionFactory by yourself and be responsible of closing the transaction and session.
uploadFile("scripts", "reports/Corporation.html");
uploadFile("scripts", "src/main/resources/reports/Corporation.html");
HtmlElement card = body.getElementsByAttribute("div", "class", "ox-card").get(2);
assertEquals("Unit price: 0.00, Unit price in pesetas: 0"), card.asText());
HtmlElement card = body.getElementsByAttribute("div", "class", "ox-card").get(2);
assertEquals("Unit price: 0.00, Unit price in pesetas: 0"), card.asNormalizedText());
assertDiscussionCommentText("discussion", 0, Strings.multiline("admin - Now", "Hi, it's me"));
assertDiscussionCommentText("discussion", 0, "admin - Now\nHi, it's me");
assertValueInList(2, "XAVA\r\n3\r\nUnit price: 0.00");
assertValueInList(2, "XAVA\n3\nUnit price: 0.00");
assertEquals(
"javascript:openxava.executeAction('openxavatest', 'Carrier', 'Effacer l"
+ (char) 145 // ANSI
+"entité courante: Etes-vous sûr(e) ?', false, 'CRUD.delete')",
deleteLink.getHrefAttribute());
assertEquals(
"javascript:openxava.executeAction('openxavatest', 'Carrier', 'Effacer l"
+ (char) 8216 // UNICODE
+"entité courante: Etes-vous sûr(e) ?', false, 'CRUD.delete')",
deleteLink.getHrefAttribute());
assertValue("description", "This is the big jUnit discussion");
assertValue("description", "<p>This is the big jUnit discussion</p>");
assertValue("city", "46540 ");
assertValue("city", "46540");
getWebClient().getOptions().setCssEnabled(true); // If you do this then...
reload(); // ...you have to add this line
CellType.NUMERIC // Instead of Cell.CELL_TYPE_NUMERIC
HyperlinkType.FILE // Instead of Hyperlink.LINK_URL
FillPatternType.SOLID_FOREGROUND // Instead of CellStyle.SOLID_FOREGROUND
HSSFColor.HSSFColorPredefined.RED // Instead of HSSFColor.RED
BorderStyle.THIN // Instead of CellStyle.BORDER_THIN
HorizontalAlignment.LEFT // Instead of CellStyle.ALIGN_LEFT
Cell cell ...
// cell.setCellType(Cell.CELL_TYPE_FORMULA); // No longer exist, not needed
cell.setCellFormula(text);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
font.setBold(true);
For migrating to OpenXava 6.6.3 from any older OpenXava version (since 1.0):
Follow the OpenXava 6.x migration instructions