Note: This file is written in Markdown and is best viewed with a Markdown viewer (e.g., GitHub, GitLab, VS Code, or a dedicated Markdown reader). Viewing it in a plain text editor may not render the formatting as intended.
Copyright (c) 2026 Software Tree
This project demonstrates the JDX ORM callback methods — JDXPreInsert(), JDXPreUpdate(), and JDXPostQuery() — which allow a domain model class to automatically transform its own data immediately before writing to the database and immediately after reading from it, without any intervention in application code.
By defining these methods directly on a model class, JDX ORM will invoke them at the appropriate points in the persistence lifecycle:
JDXPreInsert()— called automatically by JDX just before the object is inserted into the database.JDXPreUpdate()— called automatically by JDX just before the object is updated in the database.JDXPostQuery()— called automatically by JDX immediately after the object is retrieved from the database.
The User domain model class in this example uses these callbacks to implement two common data transformation patterns:
- Password encoding/decoding — the plaintext
passwordfield is encoded (usingStringEncoder) intoencodedPasswordbefore storage, and decoded back topasswordon retrieval. The plaintextpasswordfield itself is declared asIGNOREin the ORM mapping, so it is never persisted directly. - History compression/decompression — the
historyfield is compressed (using Java'sDeflater) and then encoded intocompressedAndEncodedHistorybefore storage, and decoded and decompressed back tohistoryon retrieval. Similarly, thehistoryfield isIGNOREd in the mapping.
This approach keeps the transformation logic cleanly encapsulated in the model class and completely transparent to application code — the application always works with plaintext password and history values.
- Java JDK 8 or higher installed and on the system PATH.
- JDX ORM SDK installed. Set the environment variable
JX_HOMEto the SDK's top-level installation directory. - A supported JDBC-compatible database (MySQL is pre-configured; an SQLite example is also commented out in the
.jdxfile).
JDX_PrePostMethodsExample/
├── config/
│ └── prepostmethods_example.jdx # ORM mapping specification file
├── src/
│ └── com/softwaretree/jdxprepostmethodsexample/
│ ├── PrePostMethodsExample.java # Main application entry point
│ └── model/
│ ├── User.java # User model class with callback methods
│ └── StringEncoder.java # Utility class for encoding/decoding byte arrays
├── bin/ # Compiled .class files (generated)
├── sources.txt # List of Java source files for compilation
├── compile.cmd # Windows: compile the Java source files
├── compile.sh # Mac/Linux: compile the Java source files
├── setEnvironment.bat # Windows: sets classpath environment variable
├── setEnvironment.sh # Mac/Linux: sets classpath environment variable
├── runJDXExample.bat # Windows: run the sample application
├── runJDXExample.sh # Mac/Linux: run the sample application
├── forward.bat # Windows: create/recreate the database schema
├── forward.sh # Mac/Linux: create/recreate the database schema
├── JDXDemo.bat # Windows: launch the JDXDemo GUI application
├── JDXDemo.sh # Mac/Linux: launch the JDXDemo GUI application
└── README.md # This file
| Field | Type | Persisted | Notes |
|---|---|---|---|
name |
String |
Yes | Primary key |
password |
String |
No (IGNORE) |
Plaintext password; never stored in the database |
encodedPassword |
String |
Yes | Encoded form of password; what is actually stored |
history |
String |
No (IGNORE) |
Plaintext history; never stored in the database |
compressedAndEncodedHistory |
String |
Yes | Compressed and encoded form of history; what is actually stored |
The IGNORE mapping declaration tells JDX ORM to skip password and history during all database operations — they are transient fields that exist only in memory and are populated/derived by the callback methods.
A utility class (donated by Eric van der Maarel of Nedap N.V., based on the SQLite distribution) that encodes arbitrary byte arrays into strings safe for storage in SQLite (avoiding null bytes and single-quote characters), and decodes them back. It also supports SQLite3 BLOB (X'...') notation. This class is used by User to encode/decode the password and the compressed history bytes.
JDX_DATABASEandJDBC_DRIVER— pre-configured for MySQL; a commented-out SQLite example is also included.CLASS ... User TABLE USER— maps theUserclass to theUSERtable.PRIMARY_KEY name— thenamefield is the primary key.IGNORE password history— tells JDX ORM to completely skip thepasswordandhistoryfields during all insert, update, and query operations. OnlyencodedPasswordandcompressedAndEncodedHistoryare persisted.
Refer to the JDX Database & JDBC Driver Specification Guide for configuring other databases.
Note: Update
JDX_DATABASEandJDBC_DRIVERto match your local database setup before running.
The User class defines three JDX callback methods:
JDXPreInsert():
- Encodes
password→encodedPasswordusingStringEncoder.encode(). - Compresses
historyusingjava.util.zip.Deflater(atBEST_COMPRESSIONlevel), then encodes the compressed bytes →compressedAndEncodedHistoryusingStringEncoder.encode().
JDXPreUpdate():
- Delegates entirely to
JDXPreInsert()— the same transformations apply before an update.
JDXPostQuery():
- Decodes
encodedPassword→passwordusingStringEncoder.decode(). - Decodes
compressedAndEncodedHistory, then decompresses usingjava.util.zip.Inflater→history.
Application code always sets password and history directly on the object and reads them back after queries — the encoding, compression, and reversal happen automatically and invisibly.
The entry point demonstrates the full lifecycle:
- Delete all existing
Userobjects from the database. - Insert
Mark— created with plaintextpasswordandhistory.JDXPreInsert()fires automatically, encoding the password and compressing+encoding the history before the row is written. - Insert
Steve— same pattern, with a longer history string to illustrate compression benefit. - Query all
Userobjects.JDXPostQuery()fires automatically for each retrieved object, decoding the password and decompressing+decoding the history. The printed results show the original plaintext values.
Lists all .java source files to be compiled, one per line:
./src/com/softwaretree/jdxprepostmethodsexample/model/StringEncoder.java
./src/com/softwaretree/jdxprepostmethodsexample/model/User.java
./src/com/softwaretree/jdxprepostmethodsexample/PrePostMethodsExample.java
StringEncoder is listed first as it is a dependency of User.
Compiles all Java source files listed in sources.txt and outputs .class files into the bin/ directory.
- Requires
JX_HOMEto be set to the JDX ORM SDK installation directory. - Links against
jxclasses.jar(JDX ORM library) andjson-20240303.jar(JSON support). compile.cmd— Windows batch script (supports JDK 8; a commented line supports JDK 9+).compile.sh— Mac/Linux shell script equivalent.
Windows:
compile.cmdMac/Linux:
chmod +x compile.sh # first time only
./compile.shSets the CLASSPATH environment variable to include the JDX ORM libraries and the appropriate JDBC driver JAR. Edit this file to point to the correct JDBC driver for your database before running the application.
setEnvironment.bat— Windows (uses;as classpath separator).setEnvironment.sh— Mac/Linux (uses:as classpath separator; sourced viasource ./setEnvironment.sh).
Invokes the environment setup script to configure the classpath, then runs the PrePostMethodsExample main class.
Windows:
runJDXExample.batMac/Linux:
chmod +x runJDXExample.sh # first time only
./runJDXExample.shCreates (or recreates) the database schema based on the ORM specification in the .jdx file, without running the application.
Windows:
forward -createMac/Linux:
chmod +x forward.sh # first time only
./forward.sh -createLaunches the JDXDemo desktop GUI application, which provides a graphical way to browse and interact with the database. Note that JDXDemo retrieves objects without invoking JDXPostQuery(), so the stored (encoded/compressed) values will be displayed rather than the plaintext values.
Windows:
JDXDemo.batMac/Linux:
chmod +x JDXDemo.sh # first time only
./JDXDemo.sh-
Set
JX_HOMEto the root of your JDX ORM SDK installation. -
Configure the database by editing
config/prepostmethods_example.jdx:- Update
JDX_DATABASEwith the correct connection URL and credentials. - Update
JDBC_DRIVERwith the appropriate JDBC driver class. - Update
setEnvironment.bat(Windows) orsetEnvironment.sh(Mac/Linux) to include the JDBC driver JAR on the classpath.
- Update
-
Compile the source files:
compile.cmd # Windows ./compile.sh # Mac/Linux
-
Run the sample application:
runJDXExample.bat # Windows ./runJDXExample.sh # Mac/Linux
The application will automatically create the database schema on first run (controlled by the
forceCreateSchemaflag inPrePostMethodsExample.java).
Mac/Linux tip: Run
chmod +x *.shonce in the project directory to make all shell scripts executable.
This project can be imported directly into the Eclipse IDE as an existing Java project using File → Import → Existing Projects into Workspace.
- JDX Database & JDBC Driver Specification Guide
- JDX ORM SDK documentation (included in your SDK installation under
JX_HOME)