Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Fixed box.json version number
BaseORMService.merge doesn't seem to merge entities back into session #10
Variable scoping in SQLHelper.cfc bug #9
Update build process to leverage Travis
Updated cbvalidation
to v1.1.0
Build cleanup
Replaced StringBuffer
with StringBuilder
for performance
Updated cbvalidation dependency
Prevent conditionals from being stripped from property names
Updated build for api docs and commandbox usage for dependencies
ORM Unique validation not working
updates to all dependencies
production ignore lists
https://ortussolutions.atlassian.net/browse/CCM-15 CF11Compat - arrayContainsNoCase() Is not a function
Lucee support
Create first module version
The BaseORMService is a core model CFC of the module that will provide you with a tremendous gammut of API methods to interact with ColdFusion ORM Entities.
The idea behind this support class is to provide a very good base or parent service layer that can interact with ColdFusion ORM via hibernate and entities inspired by Spring's Hibernate Template support. This means that you don't need to create a service layer CFC in order to work with ORM entities.
It provides tons of methods for query executions, paging, transactions, session metadata, caching and much more. You can either use the class on its own or create more concrete service layers by inheriting from this class.
In order to get started with the base ORM service you need to know how to get access to it. You can do this via WireBox injection DSL or by the model's ID.
The module also registers a new WireBox DSL called entityservice
which can produce virtual or base orm entity services that you can use to inject into your own event handlers or models.
entityservice
- Inject a global ORM service
entityservice:{entityName}
- Inject a Virtual entity service according to entityName
You can also request a Base ORM Service via the registered WireBox ID which is exactly the same as the entityService
DSL:
Once you have access to the injected base ORM service, you can use it in all of its glory.
Important Please check out the latest API Docs for the latest methods and functionality.
Once you have a reference to the base ORM service then you can use any of its methods to interact with ORM entities. The drawback about leveraging the base ORM model is that you cannot add custom functions to it or tell it to work on a specific entity for all operations. It is a very simple API, but if you need more control then we can start using other approaches shown below.
We also have a virtual service layer that can be mapped to specific entities and create entity driven service layers virtually. Meaning you don't have to be passing any entity names to the API methods to save you precious typing time.
This is where you create your own CFC that inherits from our Base ORM Service model and either add or override methods. You can read more about it in our Concrete Services Section
The ORM module supports the concept of dynamic finders and counters for ColdFusion ORM entities. A dynamic finder/counter looks like a real method but it is a virtual method that is intercepted by via onMissingMethod
. This is a great way for you to do finders and counters using a programmatic and visual representation of what HQL to run.
This feature works on the Base ORM Service, Virtual Entity Services and also Active Entity services. The most semantic and clear representations occur in the Virtual Entity Service and Active Entity as you don't have to pass an entity name around.
A method expression is made up of the prefixes: findBy, findAllBy, countBy
followed by the expression that combines a query upon one or more properties:
If a conditional keyword is not passed, we assume you want equality. Remember that!
IMPORTANT The ? means that you can concatenate the same pattern over and over again.
The available conditionals in ColdBox are:
LessThanEquals
- Less than or equal to passed value
LessThan
- Less than to passed value
GreaterThanEquals
- Greater than or equal to passed value
GreaterThan
- Greater than to passed value
Like
- Equivalent to the SQL like expression
NotEqual
- Not equal to the passed value
isNull
- The property must be null
isNotNull
- The property must not be null
NotBetween
- The property value must not be between two values
Between
- The property value must be between two values
NotInList
- The property value must not be in the passed in simple list or array
inList
- The property value must be in the passed in simple list or array
The only valid operators are:
And
Or
Most of the Hibernate extensions like criteria builders and even some dynamic finders and counters will have to rely on the underlying Java type in order to work. You do this in ColdFusion by using the javaCast()
function available to you. So if you are using a primary key that is an Integer
you might have to do the following in order to match your variable to the underlying Java type:
If you do not type it, then ColdFusion assumes it is a string and passes a string to Hibernate which will throw an exception as it is supposed to be an integer.
We have created two methods available to you in the base orm service, virtual service, criteria builders, active entity, etc to help you with these translations by automatically casting the values for you:
So instead of casting it manually you can just let us do the work:
This module provides you with several enhancements when interacting with the ColdFusion ORM via Hibernate. It provides you with virtual service layers, active record patterns, criteria and detached criteria queries, entity compositions, populations and so much more to make your ORM life easier!
The ColdBox ORM Module is maintained under the Semantic Versioning guidelines as much as possible.Releases will be numbered with the following format:
And constructed with the following guidelines:
Breaking backward compatibility bumps the major (and resets the minor and patch)
New additions without breaking backward compatibility bumps the minor (and resets the patch)
Bug fixes and misc changes bumps the patch
Apache 2 License: http://www.apache.org/licenses/LICENSE-2.0
Documentation: http://coldbox-orm.ortusbooks.com
The ColdBox ORM Module is a professional open source software backed by Ortus Solutions, Corp offering services like:
Custom Development
Professional Support & Mentoring
Training
Server Tuning
Security Hardening
Code Reviews
Because of His grace, this project exists. If you don't like this, then don't read it, it's not for you.
"Therefore being justified by faith, we have peace with God through our Lord Jesus Christ: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God." Romans 5:5
The BaseORMService is a core model CFC of the module that will provide you with a tremendous gammut of API methods to interact with ColdFusion ORM Entities.
The idea behind this support class is to provide a very good base or parent service layer that can interact with ColdFusion ORM via hibernate and entities inspired by Spring's Hibernate Template support. This means that you don't need to create a service layer CFC in order to work with ORM entities.
It provides tons of methods for query executions, paging, transactions, session metadata, caching and much more. You can either use the class on its own or create more concrete service layers by inheriting from this class.
In order to get started with the base ORM service you need to know how to get access to it. You can do this via WireBox injection DSL or by the model's ID.
The module also registers a new WireBox DSL called entityservice
which can produce virtual or base orm entity services that you can use to inject into your own event handlers or models.
entityservice
- Inject a global ORM service
entityservice:{entityName}
- Inject a Virtual entity service according to entityName
You can also request a Base ORM Service via the registered WireBox ID which is exactly the same as the entityService
DSL:
Once you have access to the injected base ORM service, you can use it in all of its glory.
Important Please check out the latest API Docs for the latest methods and functionality.
Once you have a reference to the base ORM service then you can use any of its methods to interact with ORM entities. The drawback about leveraging the base ORM model is that you cannot add custom functions to it or tell it to work on a specific entity for all operations. It is a very simple API, but if you need more control then we can start using other approaches shown below.
We also have a virtual service layer that can be mapped to specific entities and create entity driven service layers virtually. Meaning you don't have to be passing any entity names to the API methods to save you precious typing time.
This is where you create your own CFC that inherits from our Base ORM Service model and either add or override methods. You can read more about it in our Concrete Services Section
Let's say you are using the virtual services and base ORM service but you find that they do not complete your requirements, or you need some custom methods or change functionality. Then you will be building concrete services that inherit from the base or virtual entity services. This is the very purpose of these support classes as most of the time you will have custom requirements and your own style of coding. Here is a custom AuthorService
we created:
Then you can just inject your concrete service in your handlers, or other models like any other normal model object.
Just drop into your modules folder or use the box-cli to install
box install cborm
Unfortunately, due to the way that ORM is loaded by ColdFusion, if you are using the ORM EventHandler or ActiveEntity or any ColdBox Proxies that require ORM, you must create an Application Mapping in the Application.cfc
like this:
Lucee 4.5+
ColdFusion 9.02+
The module also registers a new WireBox DSL called entityservice
which can produce virtual or base orm entity services:
entityservice
- Inject a global ORM service
entityservice:{entityName}
- Inject a Virtual entity service according to entityName
Here are the module settings you can place in your ColdBox.cfc
under an orm
structure:
We have also migrated the UniqueValidator
from the validation module into our ORM module. It is mapped into wirebox as UniqueValidator@cborm
so you can use in your constraints like so:
There are a few properties you can instantiate a base service with or set them afterwards that affect operation. Below you can see a nice chart for them:
So if I was to base off my services on top of this gem, I can do this:
Returns the count by passing name value pairs as arguments to this function. One mandatory argument is to pass the 'entityName'. The rest of the arguments are used in the where class using AND notation and parameterized. Ex: countWhere(entityName="User",age="20");
This function returns numeric
If you pass a structure as the last argument to your dynamic finder/counter call, we will consider that by convention to be your query options.
The valid query options are:
ignorecase
: Ignores the case of sort order when you set it to true. Use this option only when you specify the sortorder parameter.
maxResults
: Specifies the maximum number of objects to be retrieved.
offset
: Specifies the start index of the resultset from where it has to start the retrieval.
cacheable
: Whether the result of this query is to be cached in the secondary cache. Default is false.
cachename
: Name of the cache in secondary cache.
timeout
: Specifies the timeout value (in seconds) for the query
Return the count of instances in the DB for the given entity name. You can also pass an optional where statement that can filter the count. Ex: count('User','age > 40 AND name="joe"'). You can even use named or positional parameters with this method: Ex: count('User','age > ? AND name = ?',[40,"joe"])
This function returns numeric
We have three types of dynamic finders and counters:
findBy
: Find ONE entity according to method signature, if more than one record is found an exception is thrown
findAllBy
: Find ALL entities according to method signature
countBy
: Give you a count of entities according to method signature
Let's say you have the following entity:
Then we could do the following:
You can also use the virtual entity service instead of active entity.
If you just use a vanilla Base ORM Service, then the first argument must be the entityName
:
Property
Type
Required
Default
Description
queryCacheRegion
string
false
ORMService.defaultCache
The name of the secondary cache region to use when doing queries via this base service
useQueryCaching
boolean
false
false
To enable the caching of queries used by this base service
eventHandling
boolean
false
true
Announce interception events on new() operations and save() operations: ORMPostNew, ORMPreSave, ORMPostSave
useTransactions
boolean
false
true
Enables ColdFusion safe transactions around all operations that either save, delete or update ORM entities
defaultAsQuery
boolean
false
true
The bit that determines the default return value for list(), createCriteriaQuery() and executeQuery() as query or array of objects
Key | Type | Required | Default |
entityName | string | Yes | --- |
Key | Type | Required | Default | Description |
entityName | any | Yes | --- | The entity to run count projections on |
criteria | array | No | [] | The array of hibernate criterion to use for the projections |
Key | Type | Required | Default |
entityName | string | Yes | --- |
useQueryCaching | boolean | No | Same as BaseService |
queryCacheRegion | string | No | Same as BaseService |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
where | string | No |
params | any | No | strucnew() | Named or positional parameters |
Deletes entities by using name value pairs as arguments to this function. One mandatory argument is to pass the 'entityName'. The rest of the arguments are used in the where class using AND notation and parameterized. Ex: deleteWhere(entityName="User",age="4",isActive=true);
This function returns numeric
Delete by using an HQL query and iterating via the results, it is not performing a delete query but it actually is a select query that should retrieve objects to remove
This function returns void
| Key | Type | Required | Default | description | | query | string | Yes | --- | | | params | any | No | --- | | | max | numeric | No | 0 | | | offfset | numeric | No | 0 | | | flush | boolean | No | false | | | transactional | boolean | No | From Property | Use transactions or not | | datasource | string | false | | The datasource to use or use the default datasource |
Update: Please use our updated objects instead so you can have much more control, granularity and coolness!
Do a hibernate criteria based query with projections. You must pass an array of criterion objects by using the Hibernate Restrictions object that can be retrieved from this service using getRestrictions(). The Criteria interface allows to create and execute object-oriented queries. It is powerful alternative to the HQL but has own limitations. Criteria Query is used mostly in case of multi criteria search screens, where HQL is not very effective.
This function returns any which can be an array or query depending on passed arguments
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
transactional | boolean | No | From Property | Use transactions not |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- | The name of the entity to delte |
id | any | Yes | --- | A single ID or array of IDs |
flush | boolean | No | false |
transactional | boolean | No | From Property | Use transactions not |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- | The entity to purge |
flush | boolean | No | false |
transactional | boolean | No | From Property | Use transactions or not |
Key | type | Required | Default | Description |
entity | any | Yes | --- |
flush | boolean | No | false |
transactional | boolean | No | From Property | Use Transactions or not |
Key | Type | Required | Default | Description |
entityName | any | Yes | --- | The entity name to run the criteria on |
criteria | array | No | [] | Array of criterion |
sortOrder | string | No |
offset | numeric | No | 0 |
max | numeric | No | 0 |
timeout | numeric | No | 0 |
Ignore | boolean | No | false |
asQuery | boolean | No | true |
Retrieve all the instances from the passed in entity name using the id argument if specified. The id can be a list of IDs or an array of IDs or none to retrieve all. If the id is not found or returns null the array position will have an empty string in it in the specified order
This function returns array of entities found
Key
Type
Required
Default
Description
query
string
No
---
params
any
No
[runtime expression]
offset
numeric
No
0
max
numeric
No
0
timeout
numeric
No
0
ignoreCase
boolean
No
false
example
any
No
---
Key
Type
Required
Default
Description
cacheName
string
No
---
datasource
string
No
---
The datasource to use
Key
Type
Required
Default
Description
entityName
any
Yes
---
id
any
Yes
---
Key
Type
Required
Default
entityName
string
Yes
---
collectionName
string
No
---
id
any
No
---
Key
Type
Required
Default
Description
entity
any
Yes
---
Key
Type
Required
Default
Description
query
string
Yes
---
params
any
No
[runtime expression]
offset
numeric
No
0
max
numeric
No
0
timeout
numeric
No
0
asQuery
boolean
No
true
unique
boolean
No
false
Return a unique result
datasource
string
No
---
Use a specific or default datasource
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
criteria | struct | Yes | --- | A structure of criteria to filter on |
Key | Type | Required | Default | Description |
query | string | No | --- |
params | any | No | [runtime expression] |
example | any | No | --- |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
criteria | struct | Yes | --- | A structure of criteria to filter on |
sortOrder | string | false | --- | The sort ordering |
Key | Type | Required | Default | Description |
example | any | Yes | --- | The entity sample |
unique | boolean | false | false | Return an array of sample data or none |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
id | any | Yes | --- |
returnNew | boolean | false | true | If id is 0 or empty and this is true, then a new entity is returned. |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
id | any | No | --- |
sortOrder | string | false | --- | The sort orering of the array |
List all of the instances of the passed in entity class name. You can pass in several optional arguments like a struct of filtering criteria, a sortOrder string, offset, max, ignorecase, and timeout. Caching for the list is based on the useQueryCaching class property and the cachename property is based on the queryCacheRegion class property.
This function returns array
Populate an entity with a structure of name-value pairs. Make sure the names of the properties match the keys in the structure.
This function returns void
INFO With composeRelationships=true, you can populate one-to-many, many-to-one, many-to-many, and one-to-one relationships from property values in the memento. For 'many-to-one' and 'one-to-one' relationships, the value of the property in the memento should be a single value of the primary key of the target entity to be loaded. For 'one-to-many' and 'many-to-many' relationships, the value of the property in the memento should a comma-delimited list or array of the primary keys of the target entities to be loaded.
Key
Type
Required
Default
Description
entityName
string
Yes
---
Key
Type
Required
Default
Description
entityName
string
Yes
---
Key
Type
Required
Default
Description
datasource
string
false
---
The default or specific datasource use
Key
Type
Required
Default
Description
entityName
any
Yes
---
Key
Type
Required
Default
Description
entityName
string
Yes
---
Key | Type | Required | Default | Description |
target | any | Yes | --- | The entity to populate |
memento | struct | Yes | --- | The structure of name-value pairs to try to populate the entity with |
scope | string | No | Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to |
trustedSetter | Boolean | No | false | Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties |
include | string | No | A list of keys to ONLY include in the population |
exclude | string | No | A list of keys to exclude from the population |
nullEmptyInclude | string | No | A list of keys to NULL when empty, specifically for ORM population. You can also specify "*" for all fields |
nullEmptyExclude | string | No | A list of keys to NOT NULL when empty, specifically for ORM population. You can also specify "*" for all fields |
composeRelationships | boolean | No | true | When true, will automtically attempt to compose relationships from memento |
Key | Type | Required | Default | Description |
entityName | any | true | --- |
properties | struct | false | {} | A structure of name-value pairs to populate the new entity with |
Key | Type | Required | Default | Description |
entity | any | Yes | --- |
Key | Type | Required | Default | Description |
datasource | string | false | --- | The default or specific datasource to use |
Key | Type | Required | Default | Description |
entityName | string | true | --- | The entity name to bind the criteria query to |
useQueryCaching | boolean | false | false | Do automatic query caching for queries |
queryCacheRegion | string | false | criterias.{entityName} | The queryCacheRegion name property for all queries in this criteria object |
Key | Type | Required | Default | Description |
entityName | string | Yes | --- |
criteria | struct | No | [runtime expression] |
sortOrder | string | No |
offset | numeric | No | 0 |
max | numeric | No | 0 |
timeout | numeric | No | 0 |
ignoreCase | boolean | No | false |
asQuery | boolean | No | true |
Key
Type
Required
Default
Description
target
any
Yes
---
The entity to populate
xml
any
Yes
---
The xml string or xml document object to populate with
root
string
false
The xml root node to start the population with, by default it uses the XMLRoot.
scope
string
No
Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
trustedSetter
Boolean
No
false
Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
include
string
No
A list of keys to ONLY include in the population
exclude
string
No
A list of keys to exclude from the population
Key
Type
Required
Default
Description
entity
any
Yes
---
Key
Type
Required
Default
Description
entities
array
Yes
---
The array of entities to persist
forceInsert
boolean
No
false
flush
boolean
No
false
transactional
boolean
No
true
Use ColdFusion transactions or not
Key
Type
Required
Default
Description
entity
any
Yes
---
forceInsert
boolean
No
false
flush
boolean
No
false
transactional
boolean
No
true
Use ColdFusion transactions or not
Key
Type
Required
Default
Description
target
any
Yes
---
The entity to populate
qry
query
Yes
---
The query to populate with
rowNumber
numeric
false
1
The row to use to populate with.
scope
string
No
---
Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
trustedSetter
Boolean
No
false
Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
include
string
No
---
A list of columns to ONLY include in the population
exclude
string
No
---
A list of columns to exclude from the population
Key
Type
Required
Default
Description
target
any
Yes
---
The entity to populate
JSONString
string
Yes
---
The JSON packet to use for population
scope
string
No
Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
trustedSetter
Boolean
No
false
Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
include
string
No
A list of keys to ONLY include in the population
exclude
string
No
A list of keys to exclude from the population
To work with Active Entity you must do a few things to tell ColdBox you want to use Active Entity and enable validation and injections:
Enable the ORM in your Application.cfc with event handling turned on, manage session and flush at request end as false.
Enable the orm configuration structure in your ConfigurationCFC to allow for ColdBox to do entity injections
Please remember that you can use ANY method found in the Base ORM Service except that you will not pass an argument of entityName anymore as you have now binded to an ORM entity. You can also visit our API for all the methods.
The inheritance is what will make your Entity come alive with tons of useful methods!
The following are vanilla configurations for enabling the ORM in ColdFusion:
This class allows you to simulate the Active Record pattern in your ORM entities by inheriting from our Active Entity class. This will make your ORM entities get all the functionality of our Virtual and Base ORM services so you can do finds, searches, listings, counts, execute queries, transaction safe deletes, saves, updates, criteria building, and even validation right from within your ORM Entity. The idea behind the Active Entity is to allow you to have a very nice abstraction to all the ColdFusion ORM capabilities (hibernate) and all of our ORM extensions like our ColdBox Criteria Builder. With Active Entity you will be able to:
Find entities using a variety of filters and conditions
ORM paging
Specify order, searches, criterias and grouping of orm listing and searches
Use DLM style hibernate operations for multiple entity deletion, saving, and updating
Check for existence of records
Check for counts using criterias
Use our extensive ColdBox Criteria Builder to build Object Oriented HQL queries
Validate your entity using our awesome validation engine
Open your config/ColdBox.cfc and either uncomment or add the following settings:
Key
Type
Required
Default
Description
entity
any
Yes
---
Our active entity object will also give you access to our validation engine by giving your ORM entities the following functions:
Important In order for validation to work, WireBox ORM entity injection must be enabled first!
ColdBox ORM Entity Injection
WireBox Standalone ORM Entity Injection
This makes it really easy for you to validate your ORM entities.
Sample:
Handlers Sample:
Please refer to the ORM:BaseORMService for all the cool methods and functionality you can use with Active Entity. Like always, refer to the latest CFC Docs for methods and arguments.
Please remember that you can use ANY method found in the Base ORM Service except that you will not pass an argument of entityName anymore as you have now bounded to that specific entity.
You just use entityNew() like you would with any ORM entity and then just call our cool methods:
The virtual entity service is another support class that can help you create virtual service layers that are bounded to a specific ORM entity for convenience. This class inherits from our Base ORM Service and allows you to do everything the base class provides, except you do not need to specify to which entityName you are working with. You can also use this class as a base class and template out its methods to more concrete usages. The idea behind this virtual entity service layer is to allow you to have a very nice abstraction to all the CF ORM capabilities (hibernate) and promote best practices.
If you override the constructor in your ORM entity, then make sure that you call the super.init() with the optional arguments below:
There are a few properties you can instantiate a base service with or set them afterwards that affect operation. Below you can see a nice chart for them:
So if I was to base off my services on top of this gem, I can do this:
queryCacheRegion
string
false
#entityName#.activeEntityCache
The name of the secondary cache region to use when doing queries via this class
useQueryCaching
boolean
false
false
The bit that tells the class to enable query caching, disabled by default
useTransactions
boolean
false
true
The bit that enables automatic hibernate transactions on all save, saveAll, update, delete methods
eventHandling
boolean
false
true
The bit that enables event handling via the ORM Event handler such as interceptions when new entities get created, saved, enabled by default.
defaultAsQuery
boolean
false
true
The bit that determines the default return value for list(), createCriteriaQuery() and executeQuery() as query or array
Property | Type | Required | Default | Description |
| string | false |
| The name of the secondary cache region to use when doing queries via this base service |
| boolean | false | false | To enable the caching of queries used by this base service |
| boolean | false | true | Announce interception events on new() operations and save() operations: ORMPostNew, ORMPreSave, ORMPostSave |
| boolean | false | true | Enables ColdFusion safe transactions around all operations that either save, delete or update ORM entities |
| boolean | false | true | The bit that determines the default return value for list(), createCriteriaQuery() and executeQuery() as query or array of objects |
The WireBox injection DSL has an injection namespace called entityService that can be used to wire in a Virtual Entity Service. You will use this DSL in conjunction with the name of the entity to manage.
Once a virtual entity service is bounded it will be injected wherever you define it. Then just use it!
Inject Content
Description
entityService:{entity}
Inject a VirtualEntityService object for usage as a service layer based off the name of the entity passed in.
You can refer to the ORM:BaseORMService methods without the entityName usage or refer to our API Docs.
Let's say you are using the virtual service but you find that they do not complete your requirements, or you need some custom methods or change functionality. Then you will be building concrete services that inherit from the virtual entity service. This is the very purpose of these support classes as most of the time you will have custom requirements and your own style of coding. Below is a sample templated service layer:
By using the ColdBox ORM event handler as your base class for your application's event handler you will inherently get the ability to talk to your ColdBox application instance and even inject objects into your ColdFusion ORM entities using WireBox. Not only that but we have also enabled the event handler to re-transmit the Hibernate Interceptions and announce them as ColdBox Interceptions. This way, you can intercept very easily the ColdBox way, create several chains, etc. The first thing you need to do is tell the CF Engine that you want to enable event handling and also which CFC will handle your global ORM entity events.
Important: You can also use the WireBox-EntityInjection approach which allows your event handler to be portable between ColdBox and Non-ColdBox applications and also allows you to NOT even create an event handler but just point it to the appropriate class.
In this basic ORM configuration structure I have two lines that deal with ORM events:
This enables the internal Hibernate interceptors and then you map a global CFC that will handle them. Mine will be in my local application's model folder named ORMEventHandler. It has to be inside of my application's folder structure in order to be able to talk to the ColdBox application. This is extremely important, as this creates the bridge between the ORM and ColdBox.
Imporant The ORM Event Handler CFC MUST exist within the application in order for the bridge to work.
By enabling the global event handler, can also be enabled to listen to these events and use them to wire up dependencies in these ORM entities and thus provide dependency injection for ORM entities. The injection takes place during the postLoad() and postNew() event cycles. All you need to do is enable ORM injection via the
Important If you have to also override the event handler's postLoad(),postNew() method, you will then need to call the super class method so the injection procedures can take place: super.postLoad(entity) super.postNew(entity)
The video below describes the entire process:
The ColdFusion documentation says that in order to create a global event handler that it must implement the CFIDE.orm.IEventHandler interface. So all you need to do is create the CFC and make it extend the core class that will provide you with all these capabilities: cborm.models.EventHandler
That's it! Just by doing this the CF ORM will call your CFC's event methods in this CFC and satisfy the interface. Of course you can override the methods, but always remember to fire off the parent class methods in order for the ColdBox interceptions to still work. You can then override each event method as needed. Below is a chart of methods you can override:
The base event handler CFC you inherit from has all the ColdBox interaction capabilities you will ever need. You can find out all its methods by referring to the API and looking at that class or by inspecting the ColdBox Proxy class, which is what is used for enabling ColdBox interactions: coldbox.system.remote.ColdboxProxy
The ColdBox Hibernate Criteria Builder is a powerful object that will help you build and execute . is extremely powerful, but some developers prefer to build queries dynamically using an object-oriented API, rather than building query strings and concatenating them in strings or buffers. The ColdBox Criteria builder offers a powerful programmatic DSL builder for Hibernate Criteria queries. You can see below some of the Hibernate documentation on criteria queries.
Hibernate Criteria Queries:
Hibernate Criteria Interface:
Hibernate Restrictions:
As you will soon discover, they are fantastic but doing it the java way is not that fun, so we took our lovely ColdFusion dynamic language funkyness and added some ColdBox magic to it.
Note The best place to see all of the functionality of the Criteria Builder is to check out the latest .
We have also expanded the hibernate ORM events to bridge the gap to the ColdBox interceptors. So now all the hibernate interceptors will relay their events to ColdBox via interceptors. This means that each hibernate event, like preLoad() for example, will announce its ColdBox counterpart: ORMPreLoad(). Below are the new interception points the ORM Event Handler exposes with the appropriate interception data it announces:
With the exposure of these interception points to your ColdBox application, you can easily create decoupled executable chains of events that respond to ORM events. This really expands the ORM interceptor capabilities to a more decoupled way of listening to ORM events. You can even create different interceptors for different ORM entity classes that respond to the same events, extend the entities with AOP, change entities at runtime, and more; how cool is that.
Method | Description |
postNew(entity) | This method is called by the ColdBox Base ORM Service Layers after a new entity has been created via its new() method. |
preLoad(entity) | This method is called before the load operation or before the data is loaded from the database. |
postLoad(entity) | This method is called after the load operation is complete. |
preInsert(entity) | This method is called just before the object is inserted. |
postInsert(entity) | This method is called after the insert operation is complete. |
preUpdate(Struct oldData,entity) | This method is called just before the object is updated. A struct of old data is passed to this method to know the original state of the entity being updated. |
postUpdate(entity) | This method is called after the update operation is complete. |
preDelete(entity) | This method is called before the object is deleted. |
postDelete(entity) | This method is called after the delete operation is complete. |
Interception Point | Intercept Structure | Description |
ORMPostNew | {entity} | Called via the postNew() event |
ORMPreLoad | {entity} | Called via the preLoad() event |
ORMPostLoad | {entity} | Called via the postLoad() event |
ORMPostDelete | {entity} | Called via the postDelete() event |
ORMPreDelete | {entity} | Called via the preDelete() event |
ORMPreUpdate | {entity,oldData} | Called via the preUpdate() event |
ORMPostUpdate | {entity} | Called via the postUpdate() event |
ORMPreInsert | {entity} | Called via the preInsert() event |
ORMPostInsert | {entity} | Called via the postInsert() event |
By default you will need to do some javaCasting() on the values in order for the criteria builder to work correctly on some values. Remember that ColdFusion is a typeless language and Java is not. However, we have added to convenience methods for you so you can just pass in values without caring about casting:
convertIDValueToJavaType(id)
convertValueToJavaType(propertyName, value)
You can also find these methods in the Base ORM services and Virtual Entity Services.
You can also use the virtual entity service by directly instantiating the coldbox.system.orm.hibernate.VirtualEntityService, configuring it and using it:
The ColdBox restrictions class allows you to create criterions upon certain properties, associations and even SQL for your ORM entities. This is the meat and potatoes of criteria queries, where you build a set of criterion to match against. The ColdBox criteria class offers almost all of the criterion methods found in the native hibernate Restrictions class (http://docs.jboss.org/hibernate/core/3.5/javadoc/org/hibernate/criterion/Restrictions.html) but if you need to add very explicit criterion directly you have access to the ColdBox Restrictions class which proxies calls to the native Hibernate class. You do this by either retrieving it from the Base/Virtual ORM services (getRestrictions()), create it manually, or the Criteria object itself has a public property called restrictions which you can use rather easily. We prefer the latter approach. Now, plese understand that the ColdBox Criteria Builder masks all this complexity and in very rare cases will you be going to our restrictions class directly. Most of the time you will just be happily concatenating methods on the Criteria Builder.
Ok, now that the formalities have been explained let's build some criterias.
The following methods alters the behavior of the executed query:
A criteria builder can be requested from our Base ORM services or a virtual service, which will bind itself automatically to the binded entity, by calling on their newCriteria() method. The corresponding class is: cborm.models.CriteriaBuilder
The arguments for the newCriteria() method are:
If you call newCriteria() from a virtual service layer, then you don't pass the entityName argument as it roots itself automatically.
Examples
Once you have an instance of the Criteria Builder class you can start adding restrictions, projections and configuration data for your query. All by concatenating methods in a nice programmatic DSL. Once all the restrictions, projections and/or configuration data are in place, you will execute the query/projections using our result methods. Please note that you can request as many new criteria builders as you like and each of them will execute different queries. So let's start with the restrictions.
To build our criteria queries we will mostly use the methods in the criteria object or go directly to the restrictions object for very explicit criterions as explained above. We will also go to the restrictions object when we do conjunctions and disjunctions, which are fancy words for AND's, OR's and NOT's. So to build criterias we will be calling these criterion methods and concatenate them in order to form a nice DSL language that describes what we will retrieve. Once we have added all the criteria then we can use several other concatenated methods to set executions options and then finally retrieve our results or do projections on our results.
So let's start with all the different supported criterion methods in the Criteria object, which are the most commonly used. If you need to use methods that are not in the Criteria object you will request them via the Restrictions object, which can proxy calls to the underlying Hibernate native Restrictions class ().
You can also use the add() method to add a manual restriction or array of restrictions to the criteria you are building.
But as you can see from the code, the facade methods are much nicer.
Note In some cases (isEq(), isIn(), etc), you may receive data type mismatch errors. These can be resolved by using on your criteria value.
Method
Description
Example
timeout(numeric timeout)
Set a timeout for the underlying JDBC query in milliseconds.
timeout( 5000 )
readOnly(boolean readOnly)
Set the read-only/modifiable mode for entities and proxies loaded by this Criteria, defaults to readOnly=true
readOnly(true)
firstResult()
Specifies the offset for the results. A value of 0 will return all records up to the maximum specified.
firstResult(11)
maxResults(numeric maxResults)
Set a limit upon the number of objects to be retrieved.
maxResults(25)
fetchSize(numeric fetchSize)
Set's the fetch size of the underlying JDBC query
fetchSize(50)
cache(cache, cacheRegion= )
Tells Hibernate whether to cache the query or not (if the query cache is enabled), and optionally choose a cache region
cache(true), cache(true,'my.cache')
cacheRegion(cacheRegion)
Tells Hibernate the cache region to store the query under
cacheRegion('my.cool.cache')
order(property,sortDir='asc',ignoreCase=false)
Specifies both the sort property (the first argument, the sort order (either 'asc' or 'desc'), and if it should ignore cases or not
order('lastName','asc',false)
Argument
Type
Required
Default
Description
entityName
string
true
---
The name of the entity to bind this criteria builder with, the initial pivot.
useQueryCaching
useQueryCaching
false
false
To allow for query caching of list() operations
queryCacheRegion
string
false
criteria.{entityName}
The name of the cache region to use
Method | Description | Example |
between(property,minValue,maxValue) | Where the property value is between two distinct values | c.between("age",10,30); |
conjunction(required array restrictionValues) | Group expressions together in a single conjunction (A and B and C...) and return the conjunction | c.conjunction( [ c.restrictions.between("balance",100,200), c.restrictions.lt("salary",20000) ] ); |
disjunction(required array restrictionValues) | Group expressions together in a single disjunction (A or B or C...) | c.disjunction( [ c.restrictions.between("balance",100,200), c.restrictions.lt("salary",20000) ] ); |
eqProperty(property, otherProperty) | Where one property must equal another | c.eqProperty("createDate","modifyDate"); |
eq(property, value) or isEq(property,value) | Where a property equals a particular value, you can also use eq() | c.eq("age",30); |
gt(property, value) or isGT(property, value) | Where a property is greater than a particular value, you can also use gt() | c.gt("publishedDate", now() ); |
gtProperty(property,otherProperty) | Where a one property must be greater than another | c.gtProperty("balance","overdraft"); |
ge(property,value) or isGE | Where a property is greater than or equal to a particular value, you can also use ge() | c.ge("age",18); |
geProperty(property, otherProperty) | Where a one property must be greater than or equal to another | c.geProperty("balance","overdraft"); |
idEQ(required any propertyValue) | Where an objects id equals the specified value | c.idEq( 4 ); |
ilike(required string property, required string propertyValue) | A case-insensitive 'like' expression | c.ilike("lastName", "maj%"); |
isIn(required string property, required any propertyValue) or in(required string property, required any propertyValue) | Where a property is contained within the specified list of values, the property value can be a collection (struct) or array or list, you can also use in() | c.isIn( "id", [1,2,3,4] ); |
isEmpty(required string property) | Where a collection property is empty | c.isEmpty("childPages"); |
isNotEmpty(required string property) | Where a collection property is not empty | c.isNotEmpty("childPages"); |
isFalse(required string property) | Where a collection property is false | c.isFalse("isPublished"); |
isNull(required string property) | Where a property is null | c.isNull("passwordProtection"); |
isNotNull(required string property) | Where a property is NOT null | c.isNotNull("publishedDate"); |
islt(required string property, required any propertyValue) or lt() | Where a property is less than a particular value, you can also use lt() | c.isLT("age", 40 ); |
ltProperty(required string property, required string otherProperty) | Where a one property must be less than another | c.ltProperty("sum", "balance"); |
isle(required string property, required any propertyValue) or le() | Where a property is less than or equal a particular value, you can also use le() | c.isLE("age", 30); |
leProperty(required string property, required string otherProperty) | Where a one property must be less than or equal to another | c.LeProperty("balance","balance2"); |
like(required string property, required string propertyValue) | Equivalent to SQL like expression | c.like("content", "%search%"); |
ne(required string property, required any propertyValue) | Where a property does not equal a particular value | c.ne("isPublished", true); |
neProperty(required string property, required any otherProperty) | Where one property does not equal another | c.neProperty("password","passwordHash"); |
sizeEq(required string property, required any propertyValue) | Where a collection property's size equals a particular value | c.sizeEq("comments",30); |
sizeGT(required string property, required any propertyValue) | Where a collection property's size is greater than a particular value | c.sizeGT("children",5); |
sizeGE(required string property, required any propertyValue) | Where a collection property's size is greater than or equal to a particular value | c.sizeGE("children", 10); |
sizeLT(required string property, required any propertyValue) | Where a collection property's size is less than a particular value | c.sizeLT("childPages", 25 ); |
sizeLE(required string property, required any propertyValue) | Where a collection property's size is less than or equal a particular value | c.sizeLE("childPages", 25 );; |
sizeNE(required string property, required any propertyValue) | Where a collection property's size is not equal to a particular value | c.sizeNE("childPages",0); |
sqlRestriction(required string sql) | Use arbitrary SQL to modify the resultset | c.sqlRestriction("char_length( lastName ) = 10"); |
and(Criterion, Criterion, ...) | Return the conjuction of N expressions as arguments | c.and( c.restrictions.eq("name","luis"), c.restrictions.gt("age",30) ); |
or(Criterion, Criterion, ….) | Return the disjunction of N expressions as arguments | c.or( c.restrictions.eq("name","luis"), c.restrictions.eq("name", "joe") ) |
not(required any criterion) or isNot() | Return the negation of an expression | c.isNot( c.restrictions.eg("age", 30) ); |
isTrue(required string property) | Returns if the property is true | c.isTrue("isPublished"); |
If you use ORM in your ColdBox apps, you are hopefully already taking full advantage of Criteria Builder, ColdBox’s powerful, programmatic DSL builder for Hibernate Criteria queries (and if you’re not using it, you should!). With the new Detached Criteria Builder, you can expand the power and flexibility of your criteria queries with support for criteria and projection subqueries, all while using the same intuitive patterns of Criteria Builder. No fuss, just more flexibility and control for your criteria queries!
"Some applications need to create criteria queries in "detached mode", where the Hibernate session is not available. It also allows you to express subqueries." Hibernate Docs
For more information about Detached Criteria and Subqueries, check out the following Hibernate documentation:
Hibernate DetachedCriteria: http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/criterion/DetachedCriteria.html
Hibernate Subqueries: http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/criterion/Subqueries.html
INFO The best place to see all of the functionality of the Detached Criteria Builder is to check out the latest API Docs.
You can also navigate associations by nesting the criterias using the createCriteria("association_name") method and then concatenating the properties of the association to query upon. You will basically be switching the pivot point of the query.
You can also use a hibernate property approach which aliases the association much how HQL approaches it by using the createAlias("associationName","alias") method:
Let's see the method signatures for these guys:
Yes, you can also create associations in Detached Criteria Builder, just like you would with Criteria Builder. Go on, make some uber-complicated queries!
Here we go!...
You can also navigate associations by nesting the criterias using the createCriteria("association_name") method and then concatenating the properties of the association to query upon. You will basically be switching the pivot point of the query.
You can also use a hibernate property approach which aliases the association much how HQL approaches it by using the createAlias("associationName","alias") method:
Let's see the method signatures for these guys:
Whether you want to create a criteria subquery, or a projection subquery, you'll first need to get a new instance of the Detached Criteria Builder class. Since all of the subqueries we're creating are being added to our main criteria query either as a criteria or a projection, we can get the Detached Criteria Builder like so:
The arguments for the createSubcriteria() method are:
Once the Detached Criteria Builder is defined, you can add projections, criterias, and associations, just like you would with a normal Criteria Builder.
Examples
You can now use the ORM:DetachedCriteriaBuilder to create programmatically create criteria and projection subqueries.
To create an instance of Detached Criteria Builder, simply call the createSubcriteria() method on your existing criteria.
The arguments for createSubcriteria() are:
Once the Detached Criteria Builder is defined, you can add projections, criterias, and associations, just like you would with Criteria Builder.
Examples
See the documentation for ORM:DetachedCriteriaBuilder for more information.
Once you have concatenated criterias together, you can execute the query via the execution methods. Please remember that these methods return the results, so they must be executed last.
Note You can call count() and list() on the same criteria, but due to the internal workings of Hibernate, you must call count() first, then list().
Our criteria builder also supports the notion of projections (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html#querycriteria-projection). A projection is used to change the nature of the results, much how a result transformer does. However, there are several projection types you can use which are great for doing counts, distinct counts, max values, sums, averages and much more. This is great when you do paging as obviously you do not want to execute two queries: one for the pagination and another for the total reuslts count. Below are the available projections you can use:
You will use them by passing them to the withProjections() method as arguments that match the projection type. The value of the argument is one, a list or an array of property names to run the projection on, with the exception of id and rowcount which take a boolean true. Also, you can pass in a string separated with a : to denote an alias on the property when doing the SQL. The alias can then be used with any restriction the criteria builder can use.
INFO If the :alias is not used, then the alias becomes the property name.
Besides using it for creating criteria subqueries, Detached Criteria Builder can also be used in conjunction with the new detachedSQLProjection() method to return a projected result based on a subquery. The detachedSQLProjection() method can be called just like any other Criteria Builder projection.
Examples
INFO If you need to use a property from the root entity in one of your criterias, simply prepend the property name with {alias}. MORE otice how a subquery method was not used in this example of the Detached Criteria Builder.
Since we’re not writing SQL, it can sometimes be frustrating to uncover why results from Criteria Builder and Detached Criteria Builder don’t match up with what you’re expecting.
An easy way to debug in these scenarios is to enable SQL logging and actually look at the query which is ultimately executed after Hibernate does it magic.
For a good guide on setting up SQL logging for ColdFusion ORM, check out
Once SQL logging is setup, you’ll be able to instantly see the SQL which is executed to deliver the result you’re getting from your criteria queries. You can then run these queries independently (such as in SQL Server Management Studio), identify where the issues are, and tweak your criteria query until it’s perfect.
When using Detached Criteria Builder for criteria or projection subqueries, you must use a projection. If you think about it from a SQL perspective, this makes sense. After all, we need our subquery to return a specific result (property values, a count, etc.) which will be compared to a property value on the root table (in the case of a criteria subquery), or which will be returned as a valid column value (in the case of a projection subquery).
All of the projections available for Criteria Builder are also available for Detached Criteria Builder.
Examples
Be careful when using projections and adding criterias to your query. Hibernate does not work well with projections and alias definitions, so if you want to add a criteria you must use this.yourPropertyName
to tell Hibernate not to use the alias and build a correct SQL.
If you are using Detached Criteria Builder for a criteria subquery, you will also need to use one of the methods from the ColdBox subqueries class. This is what will ultimately bind the subquery result to the root entity.
The most important thing to remember is that this subquery is what needs to be added as a criterion to your criteria query. So whether you are doing a simple subquery or building up a complex detached criteria, the result of one of the methods below should be what is added as a criterion to the criteria query (see example below).
Examples
All of the same criterias defined in Criteria Builder can be utilized in a Detached Criteria Builder as well. Easy, huh?
Here they go again...
To build our criteria queries we will mostly use the methods in the criteria object or go directly to the restrictions object for very explicit criterions as explained above. We will also go to the restrictions object when we do conjunctions and disjunctions, which are fancy words for AND's, OR's and NOT's. So to build criterias we will be calling these criterion methods and concatenate them in order to form a nice DSL language that describes what we will retrieve. Once we have added all the criteria then we can use several other concatenated methods to set executions options and then finally retrieve our results or do projections on our results.
So let's start with all the different supported criterion methods in the Criteria object, which are the most commonly used. If you need to use methods that are not in the Criteria object you will request them via the Restrictions object, which can proxy calls to the underlying Hibernate native Restrictions class ().
You can also use the add() method to add a manual restriction or array of restrictions to the criteria you are building.
But as you can see from the code, the facade methods are much nicer.
Note In some cases (isEq(), isIn(), etc), you may receive data type mismatch errors. These can be resolved by using on your criteria value.
Argument
Type
Required
Default
Description
entityName
string
true
---
The name of the entity to bind this detached criteria builder with.
alias
string
true
---
The alias to use for the entity
Argument
Type
Required
Default
Description
entityName
string
true
---
The name of the entity to bind this detached criteria builder with.
alias
string
true
---
The alias to use
Method
Description
Example
list(max, offset, timeout, sortOrder, ignoreCase, asQuery=false)
Execute the criterias and give you the results.
list(), list(max=50,offset=51,timeout=3000,ignoreCase=true)
get()
Retrieve one result only.
get()
count()
Does a projection on the given criteria query and gives you the row count only, great for pagination totals or running counts. Note, count() can't be called on a criteria after list() has been executed.
count()
Transform
Description
Example
avg
The name of the property to avg or a list or array of property names
withProjections(avg="salary")
count
The name of the property to count or a list or array of property names
withProjections(count="comments")
countDistinct
The name of the property to count distinct or a list or array of property names
withProjections(countDistinct="email")
distinct
The name of the property to do a distinct on, this can be a single property name a list or an array of property names
withProjections(distinct="email")
groupProperty
The name of the property to group by or a list or array of property names
withProjections(groupproperty="lastName")
max
The name of the property to max or a list or array of property names
withProjections(max="lastLogin")
min
The name of the property to min or a list or array of property names
withProjections(min="cid")
property
The name of the property to do a projected value on or a list or array of property names
withProjections(property="firstname")
sum
The name of the property to sum or a list or array of property names
withProjections(sum="balance")
rowCount
Do a row count on the criteria
withProjections(rowcount=1)
id
Return the projected identifier value
withProjections(id=1)
sqlProjection
Return projected value for sql fragment. Can accept a single config {sql,alias,property}, or an array of multiple configs.
withProjections(sqlProjection={sql="SELECT count( ) from blog where Year < 2006 and Author={alias}.Author", alias="BlogPosts", property="Author" })*
sqlGroupProjection
Return projected value for sql fragment with grouping. Can accept a single config( sql,alias,property,group}, or an array of multiple configs.
withProjections(sqlGroupProjection={sql="SELECT count( ) from blog where Year < 2006 and Author={alias}.Author", alias="BlogPosts", property="Author", group="Author" })*
detachedSQLProjection
Creates a sqlProjection() based on Detached Criteria Builder
Transform
Description
detachedSQLProtection
A single or array of DetachedCriteriaBuilders which will return the projected value
Method | Description |
detachedSQLProjection | A single or array of DetachedCriteriaBuilders which will return the projected value |
subEq(value) | Where the result of the subquery is eq to a specific value |
subEqAll(value) | Where all values in the subquery result are equal to a specific value |
subGe(value) | Where values in the subquery result are greater than or equal to a specific value |
subGeAll(value) | Where all values in the subquery result are equal to a specific value |
subGeSome(value) | Where some values in the subquery result are greater than a specific value |
subGt(value) | Where values in the subquery result are greater than a specific value |
subGtAll(required string value) | Where all values in the subquery result are greater than a specific value |
subGtSome(required string value) | Where some values in the subquery result are greater than a specific value |
subIn(required string value) | Where values in the subquery result are contained within the specified list of values |
subLe(required string value) | Where values in the subquery result are less than or equal to a specific value |
subLeAll(required string value) | Where all values in the subquery result are less than or equal to a specific value |
subLeSome(required string value) | Where some values in the subquery result are less than or equal to a specific value |
subLt(required string value) | Where values in the subquery result are less than a specific value |
subLtAll(required string value) | Where all values in the subquery result are less than a specific value |
subLtSome(required string value) | Where some values in the subquery result are less than a specific value |
subNe(required string value) | Where values in the subquery result are not equal to a specific value |
subNotIn(required string value) | Where values in the subquery result are not contained within the specified list of values |
exists | Where the subquery returns some result |
notExists | Where the subquery does not return a result |
propertyEq(required string property) | Where values in the subquery result are equal to the the specified property value |
propertyEqAll(required string property) | Where all values in the subquery result are equal to the the specified property value |
propertyGe(required string property) | Where values in the subquery result are greater than or equal to the the specified property value |
propertyGeAll(required string property) | Where all values in the subquery result are greater than or equal to the the specified property value |
propertyGeSome(required string property) | Where some values in the subquery result are greater than or equal to the the specified property value |
propertyGt(required string property) | Where values in the subquery result are greater than the the specified property value |
propertyGtAll(required string property) | Where all values in the subquery result are greater than the the specified property value |
propertyGtSome(required string property) | Where some values in the subquery result are greater than the the specified property value |
propertyIn(required string property) | Where values in the subquery result are contained in within the list of values for the specified property |
propertyLe(required string property) | Where values in the subquery result are less than or equal to the the specified property value |
propertyLeAll(required string property) | Where all values in the subquery result are less than or equal to the the specified property value |
propertyLeSome(required string property) | Where some values in the subquery result are less than or equal to the the specified property value |
propertyLt(required string property) | Where values in the subquery result are less than the the specified property value |
propertyLtAll(required string property) | Where all values in the subquery result are less than the the specified property value |
propertyLtSome(required string property) | Where some values in the subquery result are less than the the specified property value |
propertyNe(required string property) | Where values in the subquery result are not equal to the the specified property value |
propertyNotIn(required string property) | Where values in the subquery result are not contained in within the list of values for the specified property |
Method | Description | Example |
between(property,minValue,maxValue) | Where the property value is between two distinct values | c.between("age",10,30); |
conjunction(required array restrictionValues) | Group expressions together in a single conjunction (A and B and C...) and return the conjunction | c.conjunction( [ c.restrictions.between("balance",100,200), c.restrictions.lt("salary",20000) ] ); |
disjunction(required array restrictionValues) | Group expressions together in a single disjunction (A or B or C...) | c.disjunction( [ c.restrictions.between("balance",100,200), c.restrictions.lt("salary",20000) ] ); |
eqProperty(property, otherProperty) | Where one property must equal another | c.eqProperty("createDate","modifyDate"); |
eq(property, value) or isEq(property,value) | Where a property equals a particular value, you can also use eq() | c.eq("age",30); |
gt(property, value) or isGT(property, value) | Where a property is greater than a particular value, you can also use gt() | c.gt("publishedDate", now() ); |
gtProperty(property,otherProperty) | Where a one property must be greater than another | c.gtProperty("balance","overdraft"); |
ge(property,value) or isGE | Where a property is greater than or equal to a particular value, you can also use ge() | c.ge("age",18); |
geProperty(property, otherProperty) | Where a one property must be greater than or equal to another | c.geProperty("balance","overdraft"); |
idEQ(required any propertyValue) | Where an objects id equals the specified value | c.idEq( 4 ); |
ilike(required string property, required string propertyValue) | A case-insensitive 'like' expression | c.ilike("lastName", "maj%"); |
isIn(required string property, required any propertyValue) or in(required string property, required any propertyValue) | Where a property is contained within the specified list of values, the property value can be a collection (struct) or array or list, you can also use in() | c.isIn( "id", [1,2,3,4] ); |
isEmpty(required string property) | Where a collection property is empty | c.isEmpty("childPages"); |
isNotEmpty(required string property) | Where a collection property is not empty | c.isNotEmpty("childPages"); |
isFalse(required string property) | Where a collection property is false | c.isFalse("isPublished"); |
isNull(required string property) | Where a property is null | c.isNull("passwordProtection"); |
isNotNull(required string property) | Where a property is NOT null | c.isNotNull("publishedDate"); |
islt(required string property, required any propertyValue) or lt() | Where a property is less than a particular value, you can also use lt() | c.isLT("age", 40 ); |
ltProperty(required string property, required string otherProperty) | Where a one property must be less than another | c.ltProperty("sum", "balance"); |
isle(required string property, required any propertyValue) or le() | Where a property is less than or equal a particular value, you can also use le() | c.isLE("age", 30); |
leProperty(required string property, required string otherProperty) | Where a one property must be less than or equal to another | c.LeProperty("balance","balance2"); |
like(required string property, required string propertyValue) | Equivalent to SQL like expression | c.like("content", "%search%"); |
ne(required string property, required any propertyValue) | Where a property does not equal a particular value | c.ne("isPublished", true); |
neProperty(required string property, required any otherProperty) | Where one property does not equal another | c.neProperty("password","passwordHash"); |
sizeEq(required string property, required any propertyValue) | Where a collection property's size equals a particular value | c.sizeEq("comments",30); |
sizeGT(required string property, required any propertyValue) | Where a collection property's size is greater than a particular value | c.sizeGT("children",5); |
sizeGE(required string property, required any propertyValue) | Where a collection property's size is greater than or equal to a particular value | c.sizeGE("children", 10); |
sizeLT(required string property, required any propertyValue) | Where a collection property's size is less than a particular value | c.sizeLT("childPages", 25 ); |
sizeLE(required string property, required any propertyValue) | Where a collection property's size is less than or equal a particular value | c.sizeLE("childPages", 25 );; |
sizeNE(required string property, required any propertyValue) | Where a collection property's size is not equal to a particular value | c.sizeNE("childPages",0); |
sqlRestriction(required string sql) | Use arbitrary SQL to modify the resultset | c.sqlRestriction("char_length( lastName ) = 10"); |
and(Criterion, Criterion, ...) | Return the conjuction of N expressions as arguments | c.and( c.restrictions.eq("name","luis"), c.restrictions.gt("age",30) ); |
or(Criterion, Criterion, ….) | Return the disjunction of N expressions as arguments | c.or( c.restrictions.eq("name","luis"), c.restrictions.eq("name", "joe") ) |
not(required any criterion) or isNot() | Return the negation of an expression | c.isNot( c.restrictions.eg("age", 30) ); |
isTrue(required string property) | Returns if the property is true | c.isTrue("isPublished"); |