(c) 2026 Software Tree, LLC
1999 S. Bascom Avenue, Suite 700
Campbell, CA 95008
USA
https://www.softwaretree.com
----------------------------

                          Gilhari(r)
                       Version 0.8.10 (beta)

                         Release Notes 
                         -------------

                        (October 3, 2026)


Gilhari is a RESTful microservice framework for persisting JSON objects in relational databases.

The Gilhari SDK includes a detailed introduction, API documentation, as well as some sample apps using Gilhari.

Please read Gilhari_README.pdf to get started with using Gilhari.

You may also find the Gilhari API details in POSTMAN documentation at https://www.postman.com/dperiwalst/gilhari-workspace/collection/acn1jou/gilhari-rest-api

To pull the Docker image of Gilhari from dockerhub, you would need a Docker ID. If you don’t have a Docker ID, you may easily get one by signing up at https://app.docker.com/signup


Changes since the release on January 8, 2020:
---------------------------------------------

Gilhari 0.8.10  [JDX 5.29]

- The asynchronous insert, update and delete APIs return the same
  confirmation text as the synchronous ones; the trailing "; result=null"
  is gone.
- Configuration keys whose names start with _comment (for example
  _comment_credentials, written by ORM_Skyway) are treated as comments
  and no longer reported as unknown settings.
- If start-up fails with "Table or view ... not found", Gilhari adds a
  hint: some JDBC drivers (CData's, for example) report a failed login
  this way, so check the user and password as well as the table name.
- No change to HTTP status codes or other responses since 0.8.9.

Gilhari 0.8.9  [JDX 5.29]

- Invalid request parameters and bodies (deep, maxObjects,
  allowDuplicates, aggregateType, operationDetails, missing
  entity/newValues) now return 400 on every route, async and sync;
  previously 404 or 500 depending on the route. An unsupported API
  version returns 404. Errors raised by JDX while executing a request
  keep their previous codes (404 for reads, 500 for writes); response
  texts are unchanged.
- One sendError() helper and a ClientError class replace the per-route
  status handling; a last-resort error handler after the router replaces
  Express's HTML error page with a plain-text 500.
- Fixed: async DELETE deleteEntity, and the sync startStream, fetchMore
  and closeStream routes, threw inside their catch blocks and returned
  Express's HTML error page.
- package.json: express pinned to ^4.21.2.
- non_docker_tests: run Gilhari directly with node; mysqlSakila status-
  code regression (70 requests).>
- Update Gilhari_README to mention ORM_Skyway and ORMCP and healthcheck API

Includes JDX 5.29 enhancements:

Passwords no longer appear in logs. At detailed debug levels, 
JDX logs connection information to help troubleshoot connections. 
Passwords in these messages are now shown as ****, including passwords embedded 
in a JDBC URL (for example Password= or pwd=). User names and all other 
connection details are still logged as before.

Read-only data sources. When the JDBC connection reports that it's read-only, 
JDX no longer tries to create its metadata tables or the tables for mapped 
classes at start-up, and logs one informational message instead of an error. 
This removes misleading start-up errors with read-only sources such as Splunk
through the CData driver. Requesting forced schema creation on a read-only 
connection is now refused with a clear error message.

Credentials from environment variables. The environment variables 
JDX_DB_USER and JDX_DB_PASSWORD override the user name and password in the 
ORM specification. This keeps credentials out of configuration files and 
container images. A variable that is set but empty is now ignored, 
and the ORM specification's value is used.
--------------------------------------------------

- allowDuplicates=true|false on query and startStream requests sets
  JDX's QFLAG_DUPLICATES_OK, returning identical rows as separate
  objects; invalid values are rejected
- Error responses carry only the exception message: no node-java
  wrapper text, Java exception class names or stack frames; full
  detail is logged on the server
- Version 0.8.6 (gilhari_rest_server.js and package.json)

-----------------------------------------------------
Includes JDX 5.28 enhancements:

New mapping specification DB_PRIMARY_KEY_EXISTS {TRUE | FALSE} (default
TRUE). FALSE states that the database has no primary key for the
underlying table or view, so key values are not guaranteed unique;
PRIMARY_KEY remains the internal working key.

For such classes:
- Queries return every row as its own object (no merging of identical
  rows), decided per class in JDXQuery.buildObjects()
- getObjectById, and update/delete of objects, are rejected with a clear
  error; update2/delete2 with a predicate remain available
- Generated DDL has no PRIMARY KEY constraint
- getObjectModelSummary shows the line under the class

Reverse engineering emits DB_PRIMARY_KEY_EXISTS FALSE wherever it
fabricates a key, and the fabricated key now leaves out ignored and
byte[] attributes (shared ClassInfo.getFabricatedPrimaryKeyAttribs()).
Also fix the text of the no-primary-key warning.

Support column names with special characters

Columns whose names contain spaces, dots, colons, other punctuation or
non-ASCII characters, or start with a digit, are now mapped instead of
skipped or misread. Each column has a raw name, a sanitized attribute
name (e.g. "All_Traffic.action" -> All_Traffic_action) and a SQL name
quoted with the driver's identifier quote string. Reverse engineering
writes SQLMAP ... COLUMN_NAME with the quoted form; runtime and DDL use
it in all SQL. Ordinary names are unchanged.
-------------------------------------

Includes JDX 5.27 enhancements:

- Allowing explicit specification of BYREFERENCE keyword (which used 
  to be the default type of RELATIONSHIP in absence of the BYVALUE keyword)
  in the mapping specification.
- Checking for the exact matching of primary key attribute numbers and names 
  in the getObjectById() call.

Includes JDX 5.26 enhancements:

- Db2: accept DB2 as IBMDB2 alias; fix GENERIC dropping credentials
- Surface space-in-column-name and byte[]
  column exclusion warnings at the default DEBUG_LEVEL=5 (previously
  silent unless DEBUG_LEVEL<=3)
------------------------------------------------

Sanitize body-parser errors, enrich health check, bump to version 0.8.5

- Add error-handling middleware after body-parser to catch malformed
  JSON (400) and oversized payloads (413), returning clean JSON error
  responses instead of leaking Express's default HTML stack trace
  (which exposed internal node_modules paths)
- Add service_name and pid to /health/check response, so multiple
  Gilhari instances that may run on the same port over time can be
  distinguished
- Bump gilhari_version to 0.8.5

--------------------------------------------------------------

Includes JDX 5.25 enhancements:

Fix missing clearParameters() on success path in insert/update/delete

Improve handling of PreparedStatement for insert(), update(), 
and delete() calls by being aggressive about clearParameters() even 
after a successful executeUpdate().
Ordinary bound values are unaffected by this but LONG/LOB columns 
are bound as streams (setCharacterStream/setBinaryStream), 
where stale state from a prior execution may not be fully 
released without an explicit clearParameters() call.

Includes JDX 5.24 enhancements:

**Bug fixes**
- Oracle: `useFetchSizeWithLongColumn` is now automatically enabled for
  every Oracle connection (both `JDX_DBTYPE=ORACLE`/`ORACLE7` and
  `ORACLE8`/`9`/`10`), fixing `ORA-17027` on `getObjectById` and other
  operations against tables with a populated `LONG` column
  
  Timestamp strings with a fractional-seconds component longer than 
  expected were silently truncated to a fixed character length rather
  than having only the excess fractional digits trimmed — meaning 
  any text *after* the fraction (including a real UTC offset on 
  `TIMESTAMP WITH TIME ZONE`/`DATETIMEOFFSET` columns) was discarded 
  without error. A value like `"2026-07-12 09:30:00.123456 -07:00"` 
  was silently accepted and stored several hours wrong instead of 
  being rejected. Now: only fractional digits beyond the 9 supported 
  by `java.sql.Timestamp` are trimmed; everything else in the string
  — including an offset, or genuinely invalid trailing text — 
  is preserved and correctly causes rejection,

Includes JDX 5.23 enhancements:

- Fix Oracle NUMBER(p) Integer overflow; add TIMESTAMP WITH TIME ZONE /
  DATETIMEOFFSET support (v5.23)

  Oracle's scale-0 NUMBER(p) override is now precision-aware
  (p<=9 -> INTEGER unchanged, p>=19 -> DECIMAL forces BigDecimal).
  Previously collapsed every precision to INTEGER regardless of width,
  causing ORA-17026 on read and range errors on write above 2^31-1 --
  including via NUMBER(10), the conventional integer-id declaration.
 
- Add support for OracleTimestampWithTimeZoneSQLType (-101) and  SQLServerDateTimeOffsetSQLType (-155) constants.
  Maps to java.sql.Timestamp. 
  
- Exceptions thrown by JDX no longer expose stack frames or the
  exception-class-name prefix; message text is preserved. Reduces
  internal-detail leakage into calling applications while keeping
  actionable error detail intact.


JDX 5.22 enhancements:

New Feature: GENERIC Database Type — Universal JDBC Support
JDX now supports any JDBC-compliant data source through a new GENERIC pass-through mode. When JDX_DBTYPE=GENERIC is specified:

All non-JDX properties in the JDBC URL are automatically passed to the JDBC driver
Extra driver-specific properties flow through seamlessly
Both semicolon-separated (key=value) and query string (?key=value&key2=value2) URL formats are supported
This enables JDX to work with any JDBC data source without requiring explicit support to be added first.

Example:

JDX_DATABASE JDX:jdbc:customdb://host:port/db;customProp1=val1;customProp2=val2;USER=user;PASSWORD=pass;JDX_DBTYPE=GENERIC;DEBUG_LEVEL=0
All customProp values are automatically passed to the JDBC driver.

JDX 5.21 enhancements
- Improved Date/Time/Timestamp `String` handling

- Exception cause-chaining hardening

JDX 5.20 Enhancements
- New database column types support

   Oracle BINARY_FLOAT / BINARY_DOUBLE now map correctly to Float/Double 
   SQL Server MONEY / SMALLMONEY now map correctly to BigDecimal, consistent with DECIMAL/NUMERIC handling.

JDX 5.19 Enhancements
- Added handling of NCLOB column types

- Added a custom metadata mapping file for SAP HANA config\dxMetadata_saphana.jdx (CLOB data type for jdxMetaInfo attribute)

JDX 5.18 Enhancements
- Fixed: type coercion errors on JSON-originated numeric and date/time inserts

JDX 5.17 Enhancements
- Fixed: SQL string literals escaping

- Improved: RDBMS_GENERATED now exposed in object model summary.

- Fixed: UUID columns on PostgreSQL/CockroachDB — database-generated UUID primary keys now supported. 

- Updated to a newer version (05.16) of JDX that has fixes for CockroachDB detailed below.

- Fixed: UUID columns on PostgreSQL/CockroachDB. Tables with a native uuid column.

- Fixed: CockroachDB connection failure. Connecting to CockroachDB could fail immediately with a transaction-isolation error before any table access occurred. Resolved.

- All example directories have been updated with the following enhancements/fixes:
  .js → .json rename for classnames_map files,
   bin directory creation in compile.cmd and compile.sh,
   CRLF → LF line endings in .sh files,
   Executable bit restored on .sh files

- Includes a newer version (05.14) of JDX that has fixes for proper conversion of JSON String values 
  to SQL values for TIMESTAMP/DATE/TIME column types

- The Gilhari SDK is now also offered a tar.gz format for Linux/Mac (preserves executable bit on .sh files) users

- Updated to a newer version (05.12) of JDX that has preliminary support for MariaDB, YugaByte, Spanner, Databricks, and SAP Hana databases.
  Also support for database columns of National character string types NCHAR, NVARCHAR, LONGNVARCHAR, and NCLOB.

- Includes a newer version (05.11) of JDX that has preliminary support for more kinds of databases.

- Includes a newer version (05.09) of JDX that has fixes for properly handling schema names in the JDX_DATABAE specification
  and improved printing of JSON objects by JDXDemo.

- Added a new version of JDX that has fixes for properly creating a nested JSON object with 1-many-many relationships 
  and for inserting a non-decimal value into a Decimal or Numeric SQL column.

- Added an example directory gilhari_ecommerce_example showcasing a complete e-commerce microservice built with Gilhari.

- Apdated README.md files in all the example directories with more detailed information.

- Added the option of specifying 'gilhari_microservice_name' in the Gilhari configuration (gilhari_service.config) file.

- Start using softwaretree/gilhari image in all the example directories.

- Added an example directory gilhari_onetomany_example showcasing use of Gilhari with an object model having a one-to-many (BYREFERENCE) relationship between a Department and an Employee class.

- Added support for health/check endpoint to get the health status of the Gilhari microservice and its uptime.

- Made sqlite-jdbc-3.50.3.0.jar as the default JDBC driver for Gilhari.

- Added support for parsing operationDetails from query URLs in the GET REST call (for query, startStream, fetchMore, getObjectById, and access methods) and passing those details in the downstream JDX calls through JDXNode.

- Added operationDetailsDoc.pdf in the docs directory to explain the purpose of operationDetails and how to use them.

- Added some curl commands to exemplify the usage of operationDetails.

- Updated curlCommandsPopulate.sh scripts in various example directories.

- Updated README.md file for the JDX_ReverseEngineeringJSONExample example directory.

- Added JDX_DATABASE_JDBC_DRIVER_Specification_Guide.md and JDX_DATABASE_JDBC_DRIVER_Specification_Guide.html files to help in specifying database urls and JDBC drivers in the mapping (.jdx) files.

- Changed README.txt files to README.md files in all the example directories.

- Added support for getObjectModelSummary/now endpoint for GET operation to return a summary of the information about the underlying object model, such as classes (types), attributes, primary keys, relationships, etc. May be helpful to a client application like an AI LLM to generate proper API calls. 

- Added support and documentation for object caching.

- Packaged a new Postgres driver (postgresql-42.7.5.jar) in the SDK.

- Upgraded to a new JSON library (json-20240303.jar).

- Updated the Gilhari_README file with some details about the sample Gilhari microservices directories.

- Added an example directory (gilhari_relationships_implicit_attribs_example) to demonstrate support for a one-to-one relationship using the implicit attribute feature of JDX ORM such that an attribute of a referenced (contained) object is implicitly initialized by the ORM using a foreign key value derived from the referencing (containing) object. 

- Added an example directory (gilhari_relationships_inline_attribs_example) to demonstrate support for a one-to-one relationship using the INLINE mapping feature of JDX ORM, which provides the flexibility of optionally storing the attribute values of a contained (referenced) object in the same database table as the one used for storing the attribute values of the containing (referencing) object.

- Allow more complex JDBC URLs for cloud databases. 

- Added the exported file of the Postman collection (Gilhari REST API.postman_collection.json) of Gilhari Rest API in the docs directory so that you may easily access it by importing it in your Postman instance.

- Modified compiler scripts to target JDK 1.8 when compiling container classes.

- Enhanced documentation with more tips on using JDBC drivers and the database URLs.

- Enhanced the Gilhari_README file to give more details on the reverse-engineering feature and process to use existing dtabase schema and data.

- Added an example directory (JDX_ReverseEngineeringJSONExample) to demonstrate reverse engineering of an existing relational schema for a JSON object data model. You can use this example to get a jump start on using Gilhari for your legacy data in a relational database.

- Upgraded the lower level infrastructure stack

- Use JDBC driver compatible with JDK 1.8

- Added support for streaming queries by introducing startStream, fetchMore, and closeStream directives (keywords) in the GET URIs.

- Added a new example directory gilhari_streaming_example to show how the streaming queries can be used with Gilhari.

- Updated README file to explain streaming queries.

- Added support for handling some operational directives (like "projections", "ignore", "follow", and "filters") for fine-tuning the REST API calls. These directives that are specified in the body of a request can help in refining the shape of the target JSON objects. Potentially useful in implementing GraphQL Queries and Mutations.
  
- Updated infrastructure modules (ubuntu, node, openjdk)

- Improved documentation.

- Added documentation for using existing schema (and data) in legacy relational databases.

- Added an example directory to show the support of many-to-many relationship functionality in the object model.

- Improved exception handling and reporting.

- Improved Gilhari_README.pdf.

- Changed /jdx/ to /gilhari/ in the REST URLs.

- Changed the product name from RJPS to Gilhari.

Changes since the release on November 21, 2019:
-----------------------------------------------

- Improved README files in various example directories.

- Added more curl commands and scripts in the example directories.

Changes since the release on October 26, 2019:
----------------------------------------------

- Change "RJPS microservice listening at http://localhost:::" to 
  "RJPS microservice listening at http://localhost:8081".
  Also, to avoid any confusion, add a note saying that the port number may be mapped
  to another number for accessing the service from outside of Docker.

- Added an example directory to show the autoincrement functionality such that
  the database automatically generates a unique id value for a new JSON object.

- Show an error message for a DROP TABLE failure during the database schema creation
  only if debug level is 0.

- Added shell script files corresponding to the Windows .cmd files in the example directories.

- Added some curl commands to quickly check the response from the containerised app.

- Added libs and external_libs directories to support compilation of model files.

- Changed classes.txt files to contain only the relative paths to the source (.java) files.

Suggestions for fixing some common problems:
--------------------------------------------

- Database connection errors:
  These errors happen mainly for the following reasons:
 
  Problem: The database server is not running.
  Solution: Start the database server (service).

  Problem: The database URL specified using the JDX_DATABASE tag in the ORM specification (.jdx) file is not correct.
  Solution: Please make sure that you are using the correct URI for your target database. Sometimes, the "localhost" specification would not work from inside a container; you have to specify the IP address of the system where your database is running.

  Problem: The database credentials (name/password) are not correct.
  Solution: Fix them under the JDX_DATABASE tag in the ORM specification (.jdx) file. You may also override the credentials in the Gilhari service configuration (e.g. gilhari_service.config) file.

  Problem: Correct JDBC driver not found.
  Solutions: 
  1: Please make sure that the JDBC URL is correct in the JDX_DATABASE tag in the ORM specification (.jdx) file. 
  2: Please make sure that the correct JDBC driver name corresponding to your database has been specified in the JDBC_DRIVER tag in the ORM specification (.jdx) file.
  3: Please make sure that your JDBC driver (.jar) file is added in your app specific Gilhari image (check your Dockerfile) and that "jdbc_driver_path" property is set to that path in Gilhari service configuration (e.g. gilhari_service.config) file.

  Problem: The database connection errors persist even after making the changes to the ORM specification and/or the Gilhari service configuration files.
  Solution: Don't forget to update the Docker image of your app with these changes by rebuilding the image. Also, remove the old containers which might be blocking some communication ports.













