For the complete documentation index, see llms.txt. This page is also available as Markdown.

Session Management

How bx-orm manages Hibernate Sessions and SessionFactories behind the scenes

bx-orm manages Hibernate state across four layers. Understanding them helps explain behavior you'll run into in practice: why entities loaded in one request aren't visible in another, why a background thread needs its own session, and what actually happens when you call ormReload().

ORMService

ORMService is a single BoxRuntime-wide service. It keeps a map of every running ORMApp, keyed by the BoxLang Application's name, and is responsible for:

  • Starting up an ORMApp the first time an ORM-enabled application runs (startupApp())

  • Looking up the running ORMApp for a given context (getORMAppByContext())

  • Reloading an application's ORM state (reloadApp(), backing the ormReload() BIF)

  • Shutting down one application (shutdownApp()) or all of them when the runtime itself shuts down

ORMApp

An ORMApp represents one BoxLang Application's ORM state, and is built once and reused for the life of that application (until reload or shutdown). On startup it:

  1. Discovers entities via MappingGenerator, grouped by the datasource each entity belongs to

  2. Builds one Hibernate SessionFactory per datasource, via SessionFactoryBuilder

  3. Tracks which datasource is the default (from this.ormSettings.datasource)

Everything expensive - entity discovery, XML mapping generation, and Hibernate bootstrapping - happens here, once per application, not per request. This is why ormSettings.entityPaths and generateMappings=false matter so much for startup performance; see Performance.

ORMContext and Hibernate Sessions

Where ORMApp is application-scoped, ORMContext is scoped to a single request or thread context. It holds the actual Hibernate Session objects your code reads and writes through, one per datasource, opened lazily the first time that datasource is touched.

When a session is opened, its flush mode depends on autoManageSession:

  • autoManageSession = false (the default): the session is opened in FlushMode.MANUAL. Nothing is written to the database until you explicitly call ormFlush() or commit a transaction block. See Transactions.

  • autoManageSession = true: Hibernate manages flushing automatically (e.g. before query execution), which is generally discouraged - see the autoManageSession setting in Configuration.

At the end of the request or thread (or explicitly via ormCloseSession()/ormCloseAllSessions()), the ORMContext is torn down: any active transaction on each open session is committed, then the session is closed. If flushAtRequestEnd and autoManageSession are both enabled, sessions are flushed first.

Reloading the ORM (ormReload())

Calling ormReload() rebuilds the current application's ORMApp - re-discovering entities and re-building every SessionFactory - without restarting the BoxLang application itself. The rebuild is ordered carefully to stay safe under concurrent requests:

  1. Any open Hibernate sessions for the reloading request are closed first, so they can't hold a reference to a SessionFactory that's about to be replaced.

  2. The new ORMApp (with fresh session factories) is fully built before it replaces the old one in the running application map.

  3. The old ORMApp is swapped out and only then shut down, closing its old SessionFactory instances.

This ordering means other requests keep using a valid ORMApp throughout the reload, with only a small window where both the old and new session factories briefly coexist.

Relevant Built-in Functions

Function
Purpose

Get the raw Hibernate Session for the current context and datasource

Get the Hibernate SessionFactory for a datasource

Flush one or all open sessions

Detach all entities from the session without flushing

Close one or all open sessions for the current context

Rebuild the ORM application's session factories

Last updated

Was this helpful?