Skip to content

Latest commit

 

History

History
275 lines (194 loc) · 13.4 KB

File metadata and controls

275 lines (194 loc) · 13.4 KB

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_Relationships2Example

Overview

This project demonstrates two alternative storage strategies for one-to-one relationships in JDX ORMINLINE and EMBEDDED — and contrasts them with the standard BYVALUE approach used in JDX_RelationshipsExample. Both strategies store the related object's data in the same database table row as the parent object, eliminating the need for a separate table and a join, but they differ in how the data is physically stored.

Three relationship scenarios are demonstrated, each using a separate set of model classes and a dedicated database table:

Scenario 1 — INLINE relationship (SimpleEmpSimpleAddr): The attributes of the SimpleAddr object are stored as individual columns in the Simple_Employee table alongside the SimpleEmp columns. This means SimpleAddr fields are directly queryable — path expressions like address.country='USA' can be used in predicates. INLINE attributes are always retrieved, even during shallow queries.

Scenario 2 — EMBEDDED relationship (SimpleEmp2SimpleAddr2): The entire SimpleAddr2 object is serialized and stored as a single BLOB column in the Simple_Employee2 table. This is more compact and works for any Serializable object, but the individual fields of SimpleAddr2 cannot be queried directly (no path expressions in predicates). EMBEDDED attributes are not retrieved during shallow queries — a deep query or explicit refresh() is needed.

Scenario 3 — EMBEDDED relationship with a HashMap (SimpleEmpWithMultiCityAddr): The cityAddresses field, a HashMap<String, SimpleAddr2> (city name → address), is serialized and stored as a BLOB column. This shows that EMBEDDED works with standard Java collection types like HashMap and Hashtable, as long as the contained objects are Serializable. It is particularly useful when the related objects are not needed independently and foreign key queries are not required.


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 (SQLite is pre-configured; a MySQL example is also included in the .jdx file).

Project Structure

JDX_Relationships2Example/
├── config/
│   └── relationships2_example.jdx      # ORM mapping specification file
├── src/
│   └── com/softwaretree/jdxrelationships2example/
│       ├── Relationships2Example.java   # Main application entry point
│       └── model/
│           ├── SimpleAddr.java          # Address class (used with INLINE)
│           ├── SimpleAddr2.java         # Serializable address class (used with EMBEDDED)
│           ├── SimpleEmp.java           # Employee with INLINE address
│           ├── SimpleEmp2.java          # Employee with EMBEDDED address
│           └── SimpleEmpWithMultiCityAddr.java  # Employee with EMBEDDED HashMap of addresses
├── 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

Storage Strategy Comparison

Strategy Related class must be Serializable? Stored as Fields queryable? Retrieved on shallow query?
INLINE No Individual columns Yes (path exprs) Yes (always)
EMBEDDED Yes BLOB column No No (deep query needed)

Model Classes

Class Table Storage Strategy Related Type
SimpleEmp Simple_Employee INLINE SimpleAddr (individual columns)
SimpleAddr (inline in Simple_Employee)
SimpleEmp2 Simple_Employee2 EMBEDDED SimpleAddr2 (BLOB)
SimpleAddr2 (serialized in BLOB) Implements java.io.Serializable
SimpleEmpWithMultiCityAddr Simple_EmployeeWithMultiCityAddr EMBEDDED HashMap<String, SimpleAddr2> (BLOB)

Both address classes (SimpleAddr and SimpleAddr2) have the same fields: addr1, addr2 (nullable), city, state, zip, country. SimpleAddr2 additionally implements java.io.Serializable (required for EMBEDDED storage).


Key Components

config/relationships2_example.jdx — ORM Mapping File

Pre-configured for SQLite; a commented-out MySQL example is also included. Key mapping elements:

CLASS .SimpleAddr — mapped without a TABLE directive, meaning it has no independent table; its columns are always stored inline within the parent.

CLASS .SimpleEmp TABLE Simple_Employee:

  • RELATIONSHIP address REFERENCES .SimpleAddr INLINE AUTO_INSTANTIATE — stores SimpleAddr fields as individual columns in Simple_Employee. AUTO_INSTANTIATE creates a SimpleAddr object automatically on retrieval even if all inline columns are null.
  • SQLMAP FOR address.addr2 NULLABLE and SQLMAP FOR address.country NULLABLE — marks two inline SimpleAddr columns as nullable.

CLASS .SimpleAddr2 — also without an independent table; instances are serialized into a BLOB.

CLASS .SimpleEmp2 TABLE Simple_Employee2:

  • RELATIONSHIP address REFERENCES .SimpleAddr2 EMBEDDED — serializes the SimpleAddr2 object into a single BLOB column.

CLASS .SimpleEmpWithMultiCityAddr TABLE Simple_EmployeeWithMultiCityAddr:

  • RELATIONSHIP cityAddresses REFERENCES java.util.HashMap EMBEDDED — serializes a HashMap<String, SimpleAddr2> into a BLOB column. The map key is the city name; the value is a SimpleAddr2 instance.

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/.../Relationships2Example.java — Main Application

The application runs three phases via useJDXORM(), useJDXORM2(), and useJDXORM3():

Phase 1 — useJDXORM() (INLINE):

  1. Delete all existing SimpleEmp objects.
  2. Insert three SimpleEmp objects (E1, E2, E3) each with a SimpleAddr — individually and in batch.
  3. Deep query all SimpleEmp objects (shows inline SimpleAddr fields).
  4. getObjectById for E2 (shallow query) — the inline address is still retrieved because INLINE attributes are always fetched.
  5. Query SimpleEmp objects with path expression predicate address.country='USA' — demonstrates that inline fields support direct filtering.
  6. Same query with shallow flag — inline address is still returned.

Phase 2 — useJDXORM2() (EMBEDDED):

  1. Delete all existing SimpleEmp2 objects.
  2. Insert three SimpleEmp2 objects each with a SimpleAddr2.
  3. Deep query all SimpleEmp2 objects (BLOB deserialized to SimpleAddr2 objects).
  4. getObjectById for E2 (shallow query).
  5. Shallow query all SimpleEmp2 objects — address is not retrieved because EMBEDDED attributes require a deep query.
  6. refresh(emp, FLAG_DEEP, null) — demonstrates explicitly refreshing a shallowly loaded object to retrieve its embedded SimpleAddr2.

Phase 3 — useJDXORM3() (EMBEDDED HashMap):

  1. Delete all existing SimpleEmpWithMultiCityAddr objects.
  2. Insert one SimpleEmpWithMultiCityAddr (E1, John Smith) with three SimpleAddr2 entries added via addAddress() (keyed by city name).
  3. Deep query all objects; retrieve the HashMap<String, SimpleAddr2> and look up addresses for "New York" and "San Francisco" by city key.
  4. Shallow query — cityAddresses map is not retrieved.

sources.txt — Source File List

Lists all .java source files to be compiled, one per line:

./src/com/softwaretree/jdxrelationships2example/model/SimpleAddr.java
./src/com/softwaretree/jdxrelationships2example/model/SimpleAddr2.java
./src/com/softwaretree/jdxrelationships2example/model/SimpleEmp.java
./src/com/softwaretree/jdxrelationships2example/model/SimpleEmp2.java
./src/com/softwaretree/jdxrelationships2example/model/SimpleEmpWithMultiCityAddr.java
./src/com/softwaretree/jdxrelationships2example/Relationships2Example.java

This file is passed to javac using the @sources.txt argument syntax.


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 Relationships2Example 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 using the JDX ORM configuration.

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/relationships2_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 Relationships2Example.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