Skip to content

SoftwareTree/JDX_ManyToManyExample

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_ManyToManyExample

Overview

This project demonstrates how JDX ORM handles many-to-many relationships between Java objects using an intermediate join class and table.

The domain model is a classic user-group membership structure:

  • A User can belong to many Groups.
  • A Group can have many Users.

The many-to-many relationship is managed through a join class UserGroup (mapped to table USER_GRP), which holds the uId/gId pairs linking users and groups. JDX ORM uses JOIN_COLLECTION_CLASS declarations in the mapping file to define how these collections are traversed in each direction.

Key behaviors specific to many-to-many relationships in JDX ORM:

  • Deep insert on a Group or User populates the join table for the associated objects but does not recursively insert the related objects themselves — avoiding unintended duplication. Related objects must be inserted separately first (or after, if no referential integrity constraints exist at the database level).
  • Deep delete on a Group or User removes the join table entries (effectively disconnecting relationships) but does not delete the related objects on the other side.
  • Deep query fetches the related objects through the join table but avoids infinite recursion by not re-fetching the originating top-level objects.
  • Associations between existing objects can also be created directly by inserting a UserGroup join object without touching either the User or Group objects themselves.

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_ManyToManyExample/
├── config/
│   └── manytomany_example.jdx       # ORM mapping specification file
├── src/
│   └── com/softwaretree/jdxmanytomanyexample/
│       ├── ManyToManyExample.java    # Main application entry point
│       └── model/
│           ├── UserGroup.java        # Join class (User ↔ Group)
│           ├── User.java             # User model class
│           └── Group.java            # Group model class
├── 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

Class Table Primary Key Fields
UserGroup USER_GRP uId + gId uId, gId (composite primary key)
User USER uId uId, uName, groups (Vector<Group>)
Group GRP gId gId, gName, users (ArrayList<User>)

The users and groups collection fields are traversed through the join table USER_GRP via JOIN_COLLECTION_CLASS definitions. Both use different Java collection types (ArrayList for Group.users, Vector for User.groups), illustrating that JDX ORM supports multiple collection types for many-to-many relationships.


Key Components

config/manytomany_example.jdx — ORM Mapping File

This file defines the join class, the two join collection descriptors (one per direction), and the two main classes. Key elements:

  • JDX_DATABASE and JDBC_DRIVER — pre-configured for SQLite; a commented-out MySQL example is also included.
  • JDX_OBJECT_MODEL_PACKAGE — the base Java package for all model classes.
  • CLASS .UserGroup — maps the join class to USER_GRP with a composite primary key (uId gId).
  • JOIN_COLLECTION_CLASS ListUsers — defines the collection of User objects associated with a Group, traversed through UserGroup, keyed by gId, with join key uId, ordered by uName.
  • CLASS .Group — maps Group to table GRP; declares the users relationship referencing ListUsers BYVALUE with gId.
  • JOIN_COLLECTION_CLASS VectorGroups — defines the collection of Group objects associated with a User, traversed through UserGroup, keyed by uId, with join key gId. Uses VECTOR collection type.
  • CLASS .User — maps User to table USER; declares the groups relationship referencing VectorGroups BYVALUE with uId.

Note that UserGroup is declared first in the mapping file, as it must be defined before the JOIN_COLLECTION_CLASS declarations that reference it.

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/UserGroup.java — Join Class

A minimal POJO with just two fields — uId and gId — and a no-arg constructor. It represents a single row in the USER_GRP join table and can be instantiated directly to create or remove a specific user-group association without modifying either the User or Group object.

src/.../model/User.java — User Class

Has uId, uName, and a Vector<Group> collection (groups). The groups field is populated by JDX ORM on deep queries through the VectorGroups join collection.

src/.../model/Group.java — Group Class

Has gId, gName, and an ArrayList<User> collection (users). The users field is populated by JDX ORM on deep queries through the ListUsers join collection.


src/.../ManyToManyExample.java — Main Application

The entry point of the sample application. It demonstrates the following sequence, all wrapped in appropriate transactions:

  1. Deep delete all existing User objects (cascades to join table entries), then shallow delete all existing Group objects (join entries already gone).
  2. Create Group g1 with two users (u1, u2). Insert u1 and u2 first (shallow), then insert g1 (deep) to populate the join table.
  3. Shallow and deep queries for all Group and User objects, showing the difference in what is fetched.
  4. Create User u3 belonging to a new Group g2. Insert g2 first (shallow), then insert u3 (deep) to populate the join table.
  5. Associate u3 with g1 by directly inserting a UserGroup(u3.uId, g1.gId) join object — demonstrating the lightweight approach to adding relationships between existing objects.
  6. At this point: g1 has u1, u2, u3; g2 has u3; u3 belongs to both groups.
  7. JDXVIEW query (JDXVIEW_ListUsers_<className>) to list all users for gId=1.
  8. Update u3's name (shallow update) and verify the change appears in a deep query of g2.
  9. Deep delete g1 — removes join table entries for g1 but leaves u1, u2, u3 intact.
  10. At this point: g1 is gone; u1 and u2 belong to no group; u3 still belongs to g2.
  11. Final deep queries for all User and Group objects to confirm the end state.

sources.txt — Source File List

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

./src/com/softwaretree/jdxmanytomanyexample/model/UserGroup.java
./src/com/softwaretree/jdxmanytomanyexample/model/User.java
./src/com/softwaretree/jdxmanytomanyexample/model/Group.java
./src/com/softwaretree/jdxmanytomanyexample/ManyToManyExample.java

UserGroup is listed first as it has no dependencies on the other model classes.


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 ManyToManyExample 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/manytomany_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 ManyToManyExample.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 many-to-many relationships using a User–Group membership model with a UserGroup join class. Covers deep insert/delete join-table-only cascade, deep query traversal, and direct join-table manipulation using ArrayList and Vector collection types.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors