Migration notes - iDempiere 13 (technical)
Changes in inventory imports via CSV
With IDEMPIERE-7010, the UOM and Qty Entered fields in the Physical Inventory and Inventory Increase/Decrease windows were introduced. Existing CSV Import Formats for "Inventory Decrease/Increase" and "Physical Inventory" will fail and require updates, because the old Qty fields are now read-only:
- In Inventory Decrease/Increase,
QtyInternalUsemust be changed toQtyEntered. - In Physical Inventory,
QtyCountmust be changed toQtyEntered.
Changes in default server push in ZK Web UI
Release-13 was initially released with WebSocket as the default push server. After release-13-2026-04-13 it was rolled back and the default is again Atmosphere. In release-14 it has been changed again to WebSocket.
To use WebSocket in release-13, add the following to "Java Options" when running iDempiere setup: -Dorg.idempiere.ui.zk.serverpush=websocket.
MAttachment.setTitle driven by list
The column AD_Attachment.Title was managed as a free text field, but in reality it contained a list of values.
With ticket IDEMPIERE-6640, the column was changed to a list, and the values are now restricted.
If you used MAttachment.setTitle in a plugin or test for a different purpose, that code will throw an error if the value is not one of the values allowed in the list.
UUID native type in PostgreSQL and UUIDv7
A big change for PostgreSQL was implemented with ticket IDEMPIERE-6650: all UUID columns in the database were converted from VARCHAR to the native PostgreSQL UUID type. This is a recommendation from PostgreSQL that positively impacts performance and database size.
The UUIDs generated by iDempiere were also moved to the UUIDv7 standard. This is also a performance recommendation, and it allows ordering by UUID with the same order as record creation, something that was previously only possible with _ID columns.
There are implications to this change:
-
The
generate_uuidfunction usesgen_random_uuid, which is natively available in PostgreSQL since version 13. Earlier versions throw an error when applying the scriptpostgresql/202510101903_IDEMPIERE-6650-generate_uuid.sql.tipFor PostgreSQL 11 and 12, you can still use it by enabling the pgcrypto extension:
CREATE EXTENSION pgcrypto; -
The script
postgresql/202510101902_IDEMPIERE-6650-uuid.sqlcan throw an error if you have custom views using a UUID column together with aUNIONclause.warningIf this happens, drop those views (and their dependencies) before applying the script, then recreate them afterward.
-
The script
postgresql/202510101903_IDEMPIERE-6650-generate_uuid.sqlcan throw an error if you have custom views using thegenerate_uuidfunction. Apply the same solution as above: drop the views before the script runs, and recreate them afterward. This script can also fail on PostgreSQL 11 and 12, with the same pgcrypto solution described above.
Problem with some PostgreSQL queries because of the UUID changes
As part of the IDEMPIERE-6650 solution, the JDBC URL now includes stringtype=unspecified, so the PostgreSQL backend can determine the data type of parameters itself.
However, some SQL constructions are problematic for PostgreSQL, and some of these are commonly used in Jasper reports. For example, a Jasper report with the following where clause:
SELECT Name FROM C_BPartner bp WHERE ( ? IS NULL OR bp.Value=? )
throws the error org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1.
The fix is to cast the binding variable to the desired data type. In PostgreSQL that can be done with ::varchar, but this is not compatible with Oracle, so it is more portable to use the CAST function, or, for a string, concatenate with an empty string:
SELECT Name FROM C_BPartner bp WHERE ( ?||'' IS NULL OR bp.Value=? )
For more information, see the ticket comment.
Deprecated PO getters on X_ classes
The X_ classes have getter methods for every foreign key, for example X_C_Order.getC_DocType(). These getters are handy and have been widely used historically, but the way they are implemented is expensive in performance and cannot use caches at all.
With ticket IDEMPIERE-6642, these getters were deprecated.
You will probably see a lot of deprecation warnings in your custom code and plugins when migrating to release-13. These warnings are harmless, but it is recommended to migrate to better-performing, cache-aware methods when possible.
Removal of old deprecated code
This release removes several classes and methods that were deprecated more than two major versions ago. Custom plugins and customizations that still call these classes and methods will no longer compile and must be updated. See ticket IDEMPIERE-6735 for the full commit.
See Removed deprecated APIs for the complete list of removed classes and methods.
Required developer actions
- Rebuild your custom plugins and note any compilation errors related to missing classes or methods.
- For each error, replace the removed deprecated API with its recommended alternative (standard getters/setters, services, or cache-aware access patterns).
- Re-run your test suite, or perform manual regression tests, to validate that business logic continues to work as expected.
Only APIs that had been deprecated for more than two major releases were removed, following the project deprecation policy.