Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The BoxLang ORM module allows your BoxLang application to integrate with the powerful Hibernate ORM
BoxLang ORM also enables transactional persistence, where an error during a save will roll back the entire transaction to prevent leaving the database in a broken state:
bx-orm bundles Hibernate 5.6.15.FINAL
.
Add Object Relational Mapping to any boxlang app with Hibernate ORM
Use native built-in-functions (BIFs) to update and persist entities to the database (entityNew()
, entitySave()
, ormFlush()
, etc.)
Supports 80+ database dialects, from SQLServer2005
to MySQL8
and PostgreSQL
Generate your mapping XML once and never again with the autoGenMap=false
ORM configuration setting
React to entity changes with pre and post event listeners such as onPreInsert()
, onPreUpdate()
and onPreDelete()
Over 20 native BIFs:
EntityDelete()
EntityLoad()
EntityLoadByExample()
EntityLoadByPK()
EntityMerge()
EntityNameArray()
EntityNameList()
EntityNew()
EntityReload()
EntitySave()
EntityToQuery()
ORMClearSession()
ORMCloseAllSessions()
ORMEvictCollection()
ORMEvictEntity()
ORMEvictQueries()
ORMExecuteQuery()
ORMFlush()
ORMGetSession()
ORMGetSessionFactory()
ORMReload()
The allows your BoxLang application to integrate with the powerful . With Hibernate, you can interact with your database records in an object oriented fashion, using a BoxLang class to denote each record and simple getters and setters for each field value:
bx-orm is an open source BoxLang module with no license purchase necessary. If you are looking to further the development of this extension, consider .
By launching we are able to give back to the community, as well as offer premium support to enterprises looking for a level up in their Hibernate implementations. If you need performance optimization, session management or caching integrations, please .
Source Code:
Support Plans:
Bug Tracker:
Get up and running in seconds!
If you're using CommandBox to manage your BoxLang server, it's as easy as running install bx-orm
:
You may need to install bx-compat-cfml
as well for backwards-compatible ORM behaviors:
For miniserver usage outside of CommandBox, use the install-bx-module
CLI command:
Note that bx-orm currently only supports the web runtime.
More info on this documentation gitbook for bx-orm
The source code for this book is hosted in GitHub:
The majority of code examples in this book are done in cfscript
.
The information in this book is distributed “as is”, without warranty. The author and Ortus Solutions, Corp shall not have any liability to any person or entity with respect to loss or damage caused or alleged to be caused directly or indirectly by the content of this training book, software and resources described in it.
Shalom Children’s Home is one of the ministries that is dear to our hearts located in El Salvador. During the 12 year civil war that ended in 1990, many children were left orphaned or abandoned by parents who fled El Salvador. The Benners saw the need to help these children and received 13 children in 1982. Little by little, more children came on their own, churches and the government brought children to them for care, and the Shalom Children’s Home was founded.
Shalom now cares for over 80 children in El Salvador, from newborns to 18 years old. They receive shelter, clothing, food, medical care, education and life skills training in a Christian environment. The home is supported by a child sponsorship program.
We have personally supported Shalom for over 6 years now; it is a place of blessing for many children in El Salvador that either have no families or have been abandoned. This is good earth to seed and plant.
Easily configure Hibernate with BL
The ORM can be configured by a struct of settings set in this.ormSettings
in your main Application.bx
:
The full list of available properties you can use to configure the ORM are the following:
By using the ormsettings.dialect
you can tell Hibernate which specific database dialect to use for building queries. By default, Hibernate tries to inspect the datasource and define it for you. 95% of the time, this works. However, if you want a specific one, then you can use the following names or a fully qualified Java class name.
Here is an example configuration from the popular ContentBox Modular CMS application
You can define your own naming convention for table and column names by pointing this.ormSettings.namingStrategy
to a custom boxlang class:
The UnderscoreNamingStrategy.bx
class should then define two methods: getTableName()
and getColumnName()
:
Release history for all bx-orm versions
Version 1.x release notes for the BoxLang ORM Module
Fix string casting error on lazy
property annotation
Removed debugging code
No significant changes.
First iteration of this module
You can freely contribute to it and submit pull requests. The contents of this book is copyright by and cannot be altered or reproduced without author's consent. All content is provided "As-Is" and can be freely distributed.
The majority of code generation and running of examples are done via CommandBox: The ColdFusion (CFML) CLI, Package Manager, REPL -
We highly encourage contribution to this book and our open source software. The source code for this book can be found in our where you can submit pull requests.
10% of the proceeds of this book will go to charity to support orphaned kids in El Salvador - . So please donate and purchase the printed version of this book, every book sold can help a child for almost 2 months.
See the Hibernate Dialect Section:
Check out our for the latest updates and changes.
Fixed issue with default cache not being created when cache provider was empty - Resolves
Fix error starting up on non-ORM apps - Resolves
Add support for tinyint
and tinyinteger
ORM types - Resolves
Skip type conversion on version properties - Resolves
Drop ormApp instantiation in baseORMBIF - Fixes
Improve default datasource look up and throw error if empty - See
See .
Throw or log an error when class annotation on association is an empty string - Resolves
Fix support for dataType
annotation on version properties - Resolves
Implement 'index' annotation - Resolves
Implement multi-column support in column
and fkcolumn
- Resolves
Implement cache support at the property level - Resolves
See .
Implement elementType
,elementColumn
annotations - Resolves
Fixes for map collection when structkeytype
or structkeycolumn
are ignored - Resolves
Skip usage of AttributeConverter
on identifier properties - Resolves
See .
Set hibernate version in build so ORMGetHibernateVersion()
stays accurate - See
Foreign key must have same number of columns as the referenced primary key - Resolves
Missing FKColumn on To-Many Relationship Should Check the Inverse Relationship for Column data - Resolves
XMLWriter - Skip id,composite-id XML rendering on subclasses - Resolves
XML Writer - Skip generator on composite keys - Resolves
XMLWriter - Don't set insert or update on one-to-one elements - Resolves
Fix support for 'params' attribute string notation - See
See .
See .
Fixed support for custom naming strategies - See
Fixed "smart" naming strategy when entity name begins with an uppercase character - See
Move compat configuration to bx-compat-cfml - See
Fixed the two types of discriminator generation order - See
fix bag element being appended to wrong node on subclasses - See
change to use caster so that lazy=true does not error - See
Add missing date
property type - See
Add alternate spellings for big decimal and big integer - See
Add flush after commit on transaction end - See
See .
See .
Metadata parsing throws error on empty class despite skipCFCWithError
setting - Resolves
See .
EntityLoad returning incorrect results with criteria struct filter on parent properties - Resolves
Hibernate Criteria Querys using get
are returning proxies instead of the entity - Resolves
ensure proxies in session are expanded when a load is requested - See
Error on first ORM request after Application Timeout - Resolves
BoxProxy Struct Implementation causes validation exceptions - Resolves
See .
See .
Allow options as third arg to ORMExecuteQuery - See
Add handling for not null on to-one relationship - See
Attempt casting uniqueOrOrder
to string in EntityLoad BIF - See
Ignore null uniqueOrOrder
argument in EntityLoad BIF - See
Fix chicken/egg issues with app startup by lazy-initializing the EventHandler - See
WrongClassException when re-querying for the same object in a session - Resolves
Disable not-null
annotation usage on one-to-one relationships - See
fix explicit nulls on setters - See
Auto-generated has
methods are overriding declared methods in ORM entities - Resolves
x-to-one
generated hasX()
methods are not returning the correct values - Resolves
See .
See
Cache71
Support for the Caché database, version 2007.1.
CockroachDB192
Support for the CockroachDB database version 19.2.
CockroachDB201
Support for the CockroachDB database version 20.1.
CUBRID
Support for the CUBRID database, version 8.3. May work with later versions.
DB2
Support for the DB2 database, version 8.2.
DB297
Support for the DB2 database, version 9.7.
DB2390
Support for DB2 Universal Database for OS/390, also known as DB2/390.
DB2400
Support for DB2 Universal Database for iSeries, also known as DB2/400.
DB2400V7R3
Support for DB2 Universal Database for i, also known as DB2/400, version 7.3
DerbyTenFive
Support for the Derby database, version 10.5
DerbyTenSix
Support for the Derby database, version 10.6
DerbyTenSeven
Support for the Derby database, version 10.7
Firebird
Support for the Firebird database
FrontBase
Support for the Frontbase database
H2
Support for the H2 database
HANACloudColumnStore
Support for the SAP HANA Cloud database column store.
HANAColumnStore
Support for the SAP HANA database column store, version 2.x. This is the recommended dialect for the SAP HANA database. May work with SAP HANA, version 1.x
HANARowStore
Support for the SAP HANA database row store, version 2.x. May work with SAP HANA, version 1.x
HSQL
Support for the HSQL (HyperSQL) database
Informix
Support for the Informix database
Ingres
Support for the Ingres database, version 9.2
Ingres9
Support for the Ingres database, version 9.3. May work with newer versions
Ingres10
Support for the Ingres database, version 10. May work with newer versions
Interbase
Support for the Interbase database.
JDataStore
Support for the JDataStore database
McKoi
Support for the McKoi database
Mimer
Support for the Mimer database, version 9.2.1. May work with newer versions
MySQL5
Support for the MySQL database, version 5.x
MySQL5InnoDB
Support for the MySQL database, version 5.x preferring the InnoDB storage engine when exporting tables.
MySQL57InnoDB
Support for the MySQL database, version 5.7 preferring the InnoDB storage engine when exporting tables. May work with newer versions
MariaDB
Support for the MariaDB database. May work with newer versions
MariaDB53
Support for the MariaDB database, version 5.3 and newer.
Oracle8i
Support for the Oracle database, version 8i
Oracle9i
Support for the Oracle database, version 9i
Oracle10g
Support for the Oracle database, version 10g
Pointbase
Support for the Pointbase database
PostgresPlus
Support for the Postgres Plus database
PostgreSQL81
Support for the PostgrSQL database, version 8.1
PostgreSQL82
Support for the PostgreSQL database, version 8.2
PostgreSQL9
Support for the PostgreSQL database, version 9. May work with later versions.
Progress
Support for the Progress database, version 9.1C. May work with newer versions.
SAPDB
Support for the SAPDB/MAXDB database.
SQLServer
Support for the SQL Server 2000 database
SQLServer2005
Support for the SQL Server 2005 database
SQLServer2008
Support for the SQL Server 2008 database
Sybase11
Support for the Sybase database, up to version 11.9.2
SybaseAnywhere
Support for the Sybase Anywhere database
SybaseASE15
Support for the Sybase Adaptive Server Enterprise database, version 15
SybaseASE157
Support for the Sybase Adaptive Server Enterprise database, version 15.7. May work with newer versions.
Teradata
Support for the Teradata database
TimesTen
Support for the TimesTen database, version 5.1. May work with newer versions
autoGenMap
true
Specifies whether ColdFusion should automatically generate entity mappings for the persistent classes. If autogenmap=false
, the mapping should be provided in the form of .HBMXML
files.
autoManageSession
true
cacheConfig
true
cacheProvider
"ehcache"
Specifies the cache provider that ORM should use as a secondary cache. The values can be:
Ehcache
ConcurrentHashMap
The fully qualified name of the class for any other cache provider.
catalog
Specifies the default Database Catalog that ORM should use.
entityPaths
empty
Specifies the directory (or array of directories) that should be used to search for persistent CFCs to generate the mapping.
Always specify it or pay a performance startup price.
Important:
If it is not set, the extension looks at the application directory, its sub-directories, and its mapped directories to search for persistent CFCs.
datasource
application.datasource
This setting defines the data source to be utilized by the ORM. If not used, defaults to the this.datasource
in the Application.bx
dbcreate
none
update
: Creates the database according to your ORM model. It only does incremental updates. It will never remove tables, indexes, etc.
dropcreate
: Same as above but it destroys the database if it has ny content and recreates it every time the ORM is reloaded.
none
: Does not change the database at all.
dialect
autodiscover
eventHandling
false
If true, then it enables the ORM event callbacks in entities and globally via the eventHandler
eventHandler
Path to the .bx
class that will manage the global ORM events.
flushAtRequestEnd
true
Specifies if an orm flush should be called automatically at the end of a request. In our opinion this SHOULD never be true. A database persistence should be done via transaction
tags and good transaction demarcation.
logSQL
false
Specifies if the SQL queries should be logged to the console.
namingstrategy
default
ormconfig
savemapping
false
If enabled, the ORM will create the Hibernate mapping XML (*.hbmxml
) files alongside the entities. This is great for debugging your entities and relationships.
schema
The default database schema to use
secondaryCacheEnabled
false
ignoreParseErrors
false
If true
, then the ORM will ignore classes that have compile time errors in them. Use false
to throw exceptions.
sqlScript
Path to a SQL script file that will be executed after the ORM is initialized. A great way to seed a database.
useDBForMapping
true
Specifies whether the database has to be inspected to identify the missing information required to generate the Hibernate mapping.
The database is inspected to get the column data type, primary key and foreign key information.
For full Hibernate configuration support, you can create an XML file containing any configuration properties you wish to configure:
You can then populate the XML file with valid Hibernate configuration syntax:
Allows the engine to manage the Hibernate session. It is recommended not to let the engine manage it for you.
Use transaction
blocks in order to demarcate your regions that should start, flush and end a transaction.
Specifies the location of the configuration file that the secondary cache provider should use. This setting is used only when secondaryCacheEnabled=true
. See below.
See below.
The dialect to use for your database. By default Hibernate will introspect the datasource and try to figure it out. See the dialects section below. You can also use the fully Java qualified name of the class. See the section below.
Defines the naming convention to use on table and column names.
- default
: Uses the table or column names as is
- smart
: This strategy changes the logical table or column name to uppercase.
- CFC PATH
: Use your own CFC to determine naming - see .
The path to a custom Hibernate configuration file: - hibernate.properties - hibernate.bx.xml Please see
Enable the secondary cache or not. See our section.
How do Hibernate logs work in bx-orm?
There are several categories of logs generated during normal use of a bx-orm application:
bx-orm
logs
SQL logs
Hibernate logs
Logging statements generated from bx-orm itself will be output to the orm.log
file located in the boxlang runtime logs/
directory.
This log file may look something like the below when DEBUG mode is enabled:
bx-orm has the ability to log every SQL statement generated from ORM code. For example, firing entityDelete( myEntity )
will generate a DELETE
SQL statement for deleting the entity (table row) in question from the entity table.
A quick example might be this log, generated after firing entityNew( "Manufacturer", properties )
:
To enable this behavior, set this.ormSettings.logSQL
to true
in your Application.bx
:
These SQL statements will also log to the orm.log
file located in ${boxlang-home}/logs
.
Hibernate-native logging statements will also be captured in the orm.log
file located in ${boxlang-home}/logs
.
All about entity identifiers, from primary keys, and generators to composite keys and field types.
Identifier properties are denoted via fieldtype="id"
.
We highly recommend disabling updates on identifier properties via update="false"
:
The Assigned generator is the default identifier generator type, and simply allows the application (your BL) to assign identifier values prior to insertion. You can think of this as generator=none
.
A select generator will attempt to select the next identifier value from the specified selectKey
column:
The UUID generator uses Hibernate's uuid generator under the hood:
The Increment generator uses a simple incrementing value to create identifiers. Do not use in concurrent applications, as the values may no longer be unique.
There are several lesser-known identifier generator types, including:
foreign
- use a specific property from a foreign entity
seqhilo
sequence
select
- select the next value from the column denoted in selectKey
uuid
- use Hibernate's UUID generation
For more information on configuring loggers, see the documentation.
lets the application assign an identifier to the object before save() is called. This is the default strategy if no element is specified. -
Assigned generators will commonly use to assign the identifer value:
retrieves a primary key, assigned by a database trigger, by selecting the row by some unique key and retrieving the primary key value. -
uses a 128-bit UUID algorithm to generate identifiers of type string that are unique within a network (the IP address is used). The UUID is encoded as a string of 32 hexadecimal digits in length. -
Generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. Do not use in a cluster. -
Entity relationships let you define an association between two entity types.
Every relationship property must define the state of the relationship. In each case, the relationship property is defined in an entity which represents the "left" side of the relationship. If you bring a Posts
relationship into the User
entity, then from the User
entity, the User
is the left side of the relationship, and Posts
is the right.
A one to one relationship couples a single row on the left side to a single row on the right side:
One to one relationships can be seen as simply extending the entity with additional information. Since there is no possibility of multiple records per entity instance, it may be worthwhile to set lazy=false
to fetch the related entity along with any entity load:
A one to many relationship couples a single row on the left side (the "one") to multiple rows on the right side (the "many"):
You'll normally want to set lazy="true"
to (for example) avoid fetching every Post on a User:
A many to one relationship couples multiple rows on the left side (the "many") to a single row on the right side( the "one"):
Thus, a single Post can have only one Author... but an author (or a User, really) can have many Posts.
A many to many relationship allows each entity to relate to multiple rows on the opposite side. A good example might be a blog which allows multiple authors for a single blog post. Each blog post can then have multiple authors, and each author has (likely) written multiple blog posts:
The linktable
attribute is required on a many-to-many
property to set the locationfor storing join records. You can further alter the storage location via linkschema
and linkcatalog
:
On many* relationships like one-to-many
, many-to-one
, etc., you'll be manipulating the full set of items via the property name: hasAuthors()
, setAuthors()
, etc. However, this plural terminology becomes weird when used on a single item addition or removal, such as addAuthors( Author )
. For this reason, you can define a singularName=STRING
attribute to clean up your entity manipulation:
Man, you wanna get lazy? How about don't-fetch-the-data-until-you-need-it kinda lazy?
Using lazy=true
, we can tell Hibernate not to fetch the relational data unless and until a method call such as Authors()
attempts to load it. This greatly improves performance on page requests which do not need that particular data:
We can also use lazy=extra
to only retrieve the rows that we touch. This may work well if we commonly only access a few rows out of the full set of child items:
This section is missing documentation - would you care to ?
Entity properties are how we map table columns to boxlang object values. You can specify an entity property by setting persistent="true"
on any property
inside a persistent boxlang class:
By default, all properties inside a persistent=true
class are assumed to be persistent as well. Thus, we can skip the persistent=true
annotation for brevity:
persistent
boolean
Define this property as a persistent property. If false
, this property will be completely ignored from an orm standpoint.
name
string
Property name
default
string
Default value for the property. This only reaches the boxlang engine, and does not affect creation of the entity table.
column
string
Table column where the property value is stored.
dbDefault
string
Set the default value for the property.
Make sure you quote datetime dbdefault
values to avoid invalid date errors in MySQL:
There are several "type" concepts and annotations you may need to use to keep the proper format when persisting or retrieving table data. While these may look similar, they are not equivalent.
type
date
,numeric
Boxlang data type
fieldtype
column
,id
, one-to-many
Denote a special type of field, like an identifier or relationship field.
ormType
big_decimal
,timestamp
Data type for the database value.
sqlType
nvarchar
A vendor-specific SQL type used for table creation only. This can normally be ignored.
The fieldtype
attribute allows you to define the behavior and purpose of this property:
There are several options for the fieldtype
value:
column
- By far the most common, this is the default behavior of every field.
id
- Notes this field as the primary key or part of the a composite key.
collection
- Denote a collection of items - this could represent a struct, an array
timestamp
- Denote a timestamp field
primary
- Not currently used.
generator
string
One of increment
,identity
,native
,seqhilo
,uuid
,guid
,select
,foreign
, assigned
params
struct
, string
{ "table: "uuid_table", column: "uuid_value_column" }
sequence
string
selectkey
string
Only used with generator=select
. Specify the select key to use when selecting sequence values from the database.
generated
string
always
, insert
, never
.
insert
boolean
Allow inserting values to new rows.
update
boolean
Allow value updates on existing rows.
notnull
boolean
Specify a not-null constraint.
uniquekey
string
Specify a key name for a unique constraint. Useful for defining a unique constraint across multiple columns.
unique
boolean
Specify a unique constraint. Default false
.
validateParams
string
Not currently supported
validate
string
Not currently supported
These property annotations are used when setting fieldtype="collection"
and collectiontype
is either struct
or map
.
structkeycolumn
string
structkeytype
string
elementtype
string
elementcolumn
string
table
string
Define the table where the foreign items are stored.
lazy
boolean
, string
Define a lazy association retrieval type. One of true
, false
, extra
.
inverse
boolean
Specify that the association "owner" is referenced and managed on the opposite entity - not this current entity.
inversejoincolumn
string
Specify the join column on the associated entity. For inverse
associations only.
linkschema
string
Specify the schema name of the link table
linkcatalog
string
Specify the catalog name of the link table
linktable
string
Specify the name of the link table
missingRowIgnored
boolean
Do not throw an error if a foreign key has no match in the foreign entity
fkcolumn
string
orderby
string
fetch
string
cascade
string
constrained
boolean
optimisticLock
boolean
Enable optimistic locking on this association. One of all
, dirty
, version
, none
.
mappedby
string
Specify the property on the association that maps to this entity.
class
string
Specify the location of the foreign entity.
joinColumn
string
Join the foreign entity on this column in this entity.
where
string
Arbitrary SQL where clause for the relation.
singularname
Not currently supported
scale
integer
length
integer
precision
integer
formula
string
Define this property as a computed property by using a SQL query to determine the property value. Formula properties cannot be modified.
index
string
Key name for a property value index.
cacheUse
string
Define a cache type to use for this property. One of read-only
, nonstrict-read-write
, read-write
, or transactional
.
cacheName
string
Set the name of the cache to use for this property.
unSavedValue
string
Set a value to use for newly instantiated objects.
version
- Denote a version field, useful for on an entity
one-to-one
- Denote a
one-to-many
- Denote a
many-to-one
- Denote a
many-to-many
- Denote a
Only valid for one-to-one
relationships.
Looking for better support of a specific persistent attribute? .
This page is missing documentation - would you care to ?
Learn the basics of modeling ORM entities
A persistent entity is a boxlang class that is marked as a database entity via the persistent
annotation upon the class definition:
By default, the entity name will be the boxlang class file name - minus the file extension, of course. We can modify the entity name via the entityname
annotation:
And the table name via the table
annotation:
Here's the full list of available annotations for a persistent class:
persistent
boolean
false
Mark this class as an ORM entity
entityname
string
Set a custom entity name which is different than the boxlang class name
table
string
Specify the database table name
schema
string
Specify the database schema name.
catalog
string
Specify the database catalog name.
dynamicinsert
Specifies whether INSERT SQL is to be generated at runtime. Only those columns whose values are not null are included in the SQL.
dynamicinsert
boolean
false
Specifies whether INSERT SQL is to be generated at runtime. Only those columns whose values are not null are included in the SQL.
dynamicupdate
boolean
false
Specifies whether UPDATE SQL is to be generated at runtime. Only those columns whose values are not null are included in the SQL.
readonly
boolean
false
Specify whether table is readonly or not
selectbeforeupdate
boolean
Specify whether Hibernate should never perform an SQL UPDATE unless it is certain that an object is actually modified. In cases when a transient object is associated with a new session using update(), Hibernate performs an extra SQL SELECT to determine if an UPDATE is actually required.
optimisticlock
string
Determines the locking strategy. It can be any one of:all
,dirty
,version
,none
batchsize
integer
An integer value that specifies the number of records to be retrieved at a single instance.
lazy
boolean
true
Whether loading is to be done lazily or not.
rowid
string
Specify the row id
discriminatorColumn
string
Use this attribute to define the discriminator column to be used in inheritance mapping
discriminatorValue
string
Use this attribute to define the discriminator value to be used in inheritance mapping
joinColumn
string
Define a join column for inheritance mapping
embedded
boolean
Marks class as embedded, used when a class has an embedded object which also needs to be persisted along with the parent's data
cacheUse
string
Specify the caching strategy to be used for caching this entity's data in the secondary cache:read-only
cacheName
string
Specify the name of the secondary cache
saveMapping
boolean
false
Specifies whether the generated Hibernate mapping file has to be saved to disk. If you set the value to
true, the Hibernate mapping XML file is saved as {class name}.hbm.xml
in the same directory
as the boxlang class.
datasource
string
Name a specific datasource to persist this entity to.
Hibernate's secondary cache is a powerful tool that can greatly improve the performance of your application. By storing frequently accessed data in memory, the secondary cache can reduce the number of database queries that need to be made, resulting in faster response times and more efficient use of system resources. Whether you're working on a small project or a large enterprise application, the secondary cache is an essential part of any Hibernate-based system. So if you want to get the most out of your Hibernate application, take advantage of this powerful caching feature!
A secondary cache provider is a class that manages a level of caching secondary to Hibernate's main caching context - the Hibernate session. A secondary cache enables longer-running cache contexts, more fine-grained control over cache busting, and other performance-related benefits.
The only setting necessary to enable secondary caching is the secondaryCacheEnabled
setting:
To configure the caching, specify the path to an XML cache configuration file in cacheConfig
:
This ehcache.xml
cache configuration then should look something like this:
While there is a cacheProvider
setting, only EHCache (currently) is supported as a secondary cache provider.
Thus, any usage of cacheProvider
other than "ehcache"
will be ignored.
Savepoints are not currently supported on ORM transactions.
bx-orm implements a number of built-in-functions (BIFs) for loading and manipulating entities as well as managing the ORM session:
EntityDelete
allows you to delete the row associated with an instantiated entity from the database:
Only a single argument is accepted - the entity to delete - and the deletion is not persisted until the session is flushed.
Returns: null
Returns: Array
|Class
|null
Returns: Array
|Class
|null
EntityLoadByPK()
allows you to instantiate an entity using the row identified by a primary key:
Returns: Class
|null
EntityMerge()
will merge a "detached" entity (meaning, not connected to any open session) back into the session.
For example, running ormClearSession()
will detach all loaded entities from the session. If you then make changes to an entity via a setter and run ormFlush()
, those entity modifications will not be persisted unless you first merge the entity back to the session:
Returns: Class
EntityNameArray()
returns an array of all mapped entity names for the boxlang application:
EntityNameArray accepts no arguments.
Returns: Array
True to its name, EntityNameList returns a string list of all mapped entity names for the boxlang application:
You can pass a string delimiter value as the first argument, if you don't like commas:
Returns: string
The entityNew()
method allows you to create a new instance of a known entity type:
You can also pass a struct of properties to populate into the entity:
Note that if you try to populate a property which does not exist, you will get an error:
This will throw an error: class [Auto] has no function with name [setPROPTHATDOESNTEXIST]
Returns: Class
entityReload()
will reload or refresh the entity state from the database. Local, unpersisted modifications will be replaced with database values.
Here's a quick example:
Returns: null
EntitySave()
is how you save entity modifications. The changes will not persist to the database until ormFlush()
is called:
EntitySave accepts an optional boolean parameter, forceInsert
, which will tell Hibernate to skip the entity existence check and insert the entity:
Most of the time this will be unnecessary.
Returns: null
Returns: Query
Returns: Boolean
Returns: null
Returns: null
Returns: null
Returns: null
Returns: null
Returns: null
Returns: Array
|Struct
|any
Returns: null
Returns: Session
Returns: SessionFactory
Alias for ORMExecuteQuery()
.
Returns: Array
|Struct
|any
Returns: null
This page is missing documentation - would you care to ?
Please see the for all the wonderful caching strategies you can do with Hibernate.
Looking for alternate cache providers? .
This page is missing documentation - would you care to ?
Easily run actions on entity insertion, update, and more with event listeners
Hibernate ORM allows reacting to various events in the session lifecycle such as onPreInsert
, onPostUpdate
, onFlush
, etc. You can enable event handling in bx-orm by setting eventHandling
to true
in your this.ormSettings
struct:
This will enable two different event listener types for listening to Hibernate events:
To use a global event handler, you must set a path to the global event handler using the eventHandler
setting:
The EventHandler.bx
must then contain function definitions matching the ORM events you wish to listen for.
Currently, the available event names are:
onFlush
preLoad
postLoad
preInsert
postInsert
preUpdate
postUpdate
preDelete
onDelete
postDelete
onEvict
onClear
onDirtyCheck
onAutoFlush
Here's an example of an EventHandler configured for all events:
You can also listen to events on a specific entity at the entity level by adding methods to the entity (class) itself:
Here is the full list of event types which can be listened to in entity event listeners:
preLoad
postLoad
preInsert
postInsert
preUpdate
postUpdate
preDelete
onDelete
postDelete
Learn transaction management with bx-orm
A transaction is any discrete unit of work used to pool database queries and statements to execute at once. This helps us to prevent a failed update from leaving the database in a broken state.
To denote a transaction, we wrap it in the transaction{}
tag:
The transaction will automatically commit (persist) at the end of the transaction block.
Savepoints are not currently supported on ORM transactions.
Listen to all events across all entities via the
Listen to specific events on a specific entity via methods
This section is missing documentation - would you care to ?
This section is missing documentation - would you care to ?
Looking for ORM savepoint support? .
Improve your database performance with secondary caching in Hibernate ORM.
A secondary cache provider is a class which manages a level of caching that is secondary to Hibernate's main caching context - the Hibernate session. A secondary cache enables longer-running cache contexts, more fine-grained control over cache busting, and other performance-related benefits.
The only setting necessary to enable secondary caching is the secondaryCacheEnabled
setting:
To configure the caching, specify the path to an XML cache configuration file in cacheConfig
:
This ehcache.xml
cache configuration then should look something like this:
Notice how our ehcache.xml
defines a default cache configuration?
We highly recommend adding a cache configuration for each cacheable entity. This will help you optimize caching, and will silence error logs like the below:
Here's a quick example. Say we have an Autos.bx
persistent class with caching enabled:
For this entity, we'll want to create a <cache></cache>
entry with a name
attribute that matches the entity name OR our cacheName
class annotation:
While there is a cacheProvider
setting, only EHCache (currently) is supported as a secondary cache provider.
Thus, any usage of cacheProvider
other than "ehcache"
will be ignored.