Skip to content

SoftwareTree/JDX_PrePostMethodsExample

Repository files navigation

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

JDX_PrePostMethodsExample

Overview

This project demonstrates the JDX ORM callback methodsJDXPreInsert(), 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 password field is encoded (using StringEncoder) into encodedPassword before storage, and decoded back to password on retrieval. The plaintext password field itself is declared as IGNORE in the ORM mapping, so it is never persisted directly.
  • History compression/decompression — the history field is compressed (using Java's Deflater) and then encoded into compressedAndEncodedHistory before storage, and decoded and decompressed back to history on retrieval. Similarly, the history field is IGNOREd 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.


Prerequisites

  • Java JDK 8 or higher installed and on the system PATH.
  • JDX ORM SDK installed. Set the environment variable JX_HOME to 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 .jdx file).

Project Structure

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

Domain Model

User

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.

StringEncoder

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.


Key Components

config/prepostmethods_example.jdx — ORM Mapping File

  • JDX_DATABASE and JDBC_DRIVER — pre-configured for MySQL; a commented-out SQLite example is also included.
  • CLASS ... User TABLE USER — maps the User class to the USER table.
  • PRIMARY_KEY name — the name field is the primary key.
  • IGNORE password history — tells JDX ORM to completely skip the password and history fields during all insert, update, and query operations. Only encodedPassword and compressedAndEncodedHistory are persisted.

Refer to the JDX Database & JDBC Driver Specification Guide for configuring other databases.

Note: Update JDX_DATABASE and JDBC_DRIVER to match your local database setup before running.


src/.../model/User.java — User Model Class with Callbacks

The User class defines three JDX callback methods:

JDXPreInsert():

  • Encodes passwordencodedPassword using StringEncoder.encode().
  • Compresses history using java.util.zip.Deflater (at BEST_COMPRESSION level), then encodes the compressed bytes → compressedAndEncodedHistory using StringEncoder.encode().

JDXPreUpdate():

  • Delegates entirely to JDXPreInsert() — the same transformations apply before an update.

JDXPostQuery():

  • Decodes encodedPasswordpassword using StringEncoder.decode().
  • Decodes compressedAndEncodedHistory, then decompresses using java.util.zip.Inflaterhistory.

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.


src/.../PrePostMethodsExample.java — Main Application

The entry point demonstrates the full lifecycle:

  1. Delete all existing User objects from the database.
  2. Insert Mark — created with plaintext password and history. JDXPreInsert() fires automatically, encoding the password and compressing+encoding the history before the row is written.
  3. Insert Steve — same pattern, with a longer history string to illustrate compression benefit.
  4. Query all User objects. JDXPostQuery() fires automatically for each retrieved object, decoding the password and decompressing+decoding the history. The printed results show the original plaintext values.

sources.txt — Source File List

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.


compile.cmd / compile.sh — Compilation Scripts

Compiles all Java source files listed in sources.txt and outputs .class files into the bin/ directory.

  • Requires JX_HOME to be set to the JDX ORM SDK installation directory.
  • Links against jxclasses.jar (JDX ORM library) and json-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.cmd

Mac/Linux:

chmod +x compile.sh   # first time only
./compile.sh

setEnvironment.bat / setEnvironment.sh — Environment Setup

Sets 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 via source ./setEnvironment.sh).

runJDXExample.bat / runJDXExample.sh — Run Script

Invokes the environment setup script to configure the classpath, then runs the PrePostMethodsExample main class.

Windows:

runJDXExample.bat

Mac/Linux:

chmod +x runJDXExample.sh   # first time only
./runJDXExample.sh

forward.bat / forward.sh — Schema Generation

Creates (or recreates) the database schema based on the ORM specification in the .jdx file, without running the application.

Windows:

forward -create

Mac/Linux:

chmod +x forward.sh   # first time only
./forward.sh -create

JDXDemo.bat / JDXDemo.sh — JDXDemo GUI

Launches 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.bat

Mac/Linux:

chmod +x JDXDemo.sh   # first time only
./JDXDemo.sh

Getting Started

  1. Set JX_HOME to the root of your JDX ORM SDK installation.

  2. Configure the database by editing config/prepostmethods_example.jdx:

    • Update JDX_DATABASE with the correct connection URL and credentials.
    • Update JDBC_DRIVER with the appropriate JDBC driver class.
    • Update setEnvironment.bat (Windows) or setEnvironment.sh (Mac/Linux) to include the JDBC driver JAR on the classpath.
  3. Compile the source files:

    compile.cmd          # Windows
    ./compile.sh         # Mac/Linux
  4. 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 forceCreateSchema flag in PrePostMethodsExample.java).

Mac/Linux tip: Run chmod +x *.sh once in the project directory to make all shell scripts executable.


Importing into Eclipse

This project can be imported directly into the Eclipse IDE as an existing Java project using File → Import → Existing Projects into Workspace.


Additional Resources

About

Demonstrates JDX ORM lifecycle callbacks JDXPreInsert, JDXPreUpdate, and JDXPostQuery. A User model transparently encodes passwords and compresses history strings before writing to the database, then decodes and decompresses on retrieval — all invisible to application code.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors