Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
SQL restrictions will allow you to add ad-hoc SQL to the criteria you are building. Simple enough, but we have made great strides to make this look easy for a developer but behind the scenes we take each sql you pass and compile it so we can abstract all the native Java types for you. This means that you can use it in a similar manner to executeQuery()
in CFML.
The method you will use for this restriction is sql()
The method takes in two arguments:
sql
- The ad-hoc query to execute. You can use positional parameters via the ?
placeholder.
params
- An array of parameters to bind the SQL with, can be simple values or a struct of a values and a supported type or a combination of both.
The parameters you bind the SQL with can be of two types
Plain values.
Typed values
If you use plain values, then we will INFER the type from it, which is not as accurate as using a typed value. A typed value is a struct with the value and a valid type.
Below you can see the TYPES
struct available in the criteria builder object which map the CFML types to the native Hibernate Types.
The inferred types we infer are the following and in the following order.
Binary
Boolean
Time
Date
uuid
float
numeric
url
string
text
The following methods alters the behavior of the executed query, some can be a life saver, so check them all out.
You can also tell Hibernate to transform the results to other formats for you once you retrieve them.
asDistinct()
- Applies a result transformer of DISTINCT_ROOT_ENTITY
asStruct()
- Applies a result transformer of ALIAS_TO_ENTITY_MAP so you get an array of structs instead of array of objects
asStream()
- Get the results as a CBstream
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.
So the idea is the you request a query, add all kinds of restrictions and modifiers and then you request the results from it.
Get the record count using hibernate projections for the given criterias. You can optionally pass in the name of the property to do the count on, else it doesn *
by default.
Convenience method to return a single instance that matches the built up criterias, or null
if the query returns no results. It can also throw the following exception: NonUniqueResultException - if there is more than one matching result. It can also take in a property list in the properties
argument so instead of giving you a full ORM entity object, it will give you a struct of those properties.
Convenience method to return a single instance that matches the built up criterias, or throw an exception (EntityNotFound
) if the query returns no results. It can also throw the following exception: NonUniqueResultException - if there is more than one matching result. It can also take in a property list in the properties
argument so instead of giving you a full ORM entity object, it will give you a struct of those properties.
Execute the criteria queries you have defined and return the results, you can pass optional parameters to manipulate the way the results are sent back to you. Let's look at the method signature for this awesome method:
As you can see from the signature above, the first two arguments (offset, max
) are used for pagination. So you can easily paginate the result set. The timeout
argument can be used if the query is expected to be heavy duty, we want to make sure we timeout the execution (throws exception). The ignorecase
is only used for sorting orders.
Tip: 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()
.
You can navigate associations in criteria queries in several ways:
Dot notation for many-to-one relationships ONLY
Helper methods to create inner criterias or joins: createCriteria(), joinTo()
This type of navigation is the easiest but ONLY works with many-to-one
associations. Let's say you have a User entity with a Role and the Role has the following properties: id, name, slug
and you want to get all users that have the role slug of admin
and are active. Then you could do this:
You can also use the joinTo()
method, which previously was called createAlias()
to create joins to related associations. Let's check out the method signature first:
The arguments can be further explained below:
associationName
: This is the name of the property on the target entity that is the association
alias
: This is the alias to assign it so you can reference it later in the criterions following it
joinType
: By default it is an inner join. The available joins are: INNER_JOIN, FULL_JOIN, LEFT_JOIN
withClause
: This is the criterion (so it's a restriction) to be added to the join condition, basically the ON
clause.
The last journey to query on associations is to pivot the root entity of the criteria to an association. This means that you will create a new criteria object based on the previous criteria, but now the target entity is the one you assign. PHEW! That's a mouthful. Basically, it's a nice way to traverse into the join and stay in that entity.
This is accomplished via the createCriteria()
method or the nice dynamic alias: with{entity}
() method.
The arguments can be further explained below:
associationName
: This is the name of the property on the target entity that is the association
alias
: This is the alias to assign it so you can reference it later in the criterions following it
joinType
: By default it is an inner join. The available joins are: INNER_JOIN, FULL_JOIN, LEFT_JOIN
withClause
: This is the criterion (so it's a restriction) to be added to the join condition, basically the ON
clause.
Now remember that you are rooting the criteria in this association, so you can't go back to the original entity properties.
We have created several methods available to you in the criteria builders to help you with casting ColdFusion values to Java values so you can use them in Criteria Queries. Most of the time the engines can do this for us but not always, so we would recommend to just use these convenience methods when needed.
Please note that the base services also include these methods with a few differences in arguments. Just check the API Docs for their usage.
BaseBuilder
Casting MethodsnullValue()
Produce a null value that can be used anywhere you like!
autoCast( propertyName, value )
This method allows you to cast any value to the appropriate type in Java for the property passed in.
idCast( id )
This method allows you to cast the identifier value to the appropriate type in Java.
So instead of casting it manually you can just let us do the work by calling these methods from any of the services.
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 criteria to match against or in SQL terms, your WHERE
statements.
The ColdBox criteria class offers most of the criterion methods found in the native hibernate Restrictions class:
If one isn't defined in the CFML equivalent, just call it as it appears in the Javadocs and we will proxy the call to the native Hibernate class for you.
You can get a direct reference to the Restrictions class via the Base/Virtual ORM services (getRestrictions())
, or the Criteria object itself has a public property called restrictions
which you can use rather easily. We prefer the latter approach. Now, please 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.
To build our criteria queries we can 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. 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.
Where the property value is between two distinct values
Group expressions together in a single conjunction (A and B and C...) and return the conjunction
Group expressions together in a single disjunction (A or B or C...)
Where a property equals a particular value, you can also use eq()
Where a property is greater than a particular value, you can also use gt()
Where a one property must be greater than another
Where a property is greater than or equal to a particular value, you can also use ge()
Where one property must be greater than or equal to another
Where an object's id equals the specified value
A case-insensitive 'like' expression
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()
Where a collection property is empty
Where a collection property is not empty
Where a collection property is false
Where a property is null
Where a property is NOT null
Where a property is less than a particular value, you can also use lt()
Where a one property must be less than another
Where a property is less than or equal a particular value, you can also use le()
Where a one property must be less than or equal to another
Equivalent to SQL like expression
Where a property does not equal a particular value
Where one property does not equal another
Where a collection property's size equals a particular value
Where a collection property's size is greater than a particular value
Where a collection property's size is greater than or equal to a particular value
Where a collection property's size is less than a particular value
Where a collection property's size is less than or equal a particular value
Where a collection property's size is not equal to a particular value
Use arbitrary SQL to modify the resultset
Return the conjuction of N expressions as arguments
Return the disjunction of N expressions as arguments
Return the negation of an expression. You can also use not()
Returns if the property is true
In some cases (isEq(), isIn(),
etc), you may receive data type mismatch errors. These can be resolved by using JavaCast on your criteria value or use our auto caster methods: idCast(), autoCast()
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.
Every restriction method you see above or in the docs can also be negated very easily by just prefixing the method with a not
.
There are times where you need if statements in order to add criterias based on incoming input. That's ok, but we can do better by adding a when( test, target )
function that will evaluate the test
argument or expression. If it evaluates to true then the target closure is called for you with the criteria object so you can do your criterias:
Hibernate provides several ways to retrieve data from the database. We have seen the normal entity loading operations in our basic CRUD and we have seen several HQL and SQL query methods as well. The last one is the .
The ColdBox Hibernate Criteria Builder is a powerful object that will help you build and execute in a fluent and dynamic manner. 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. This is error prone, syntax crazy and sometimes untestable.
The ColdBox Criteria Builders offers a powerful programmatic DSL builder for Hibernate Criteria queries. It focuses on a criteria object that you will build up to represent the query to execute. The cool thing is that you can even retrieve the exact HQL or even SQL the criteria query will be executing. You can get the explain plans, provide query hints and much more. In our experience, criteria queries will make your life much easier when doing complicated queries.
Tip: You don't have to use the ORM for everything. Please be pragmatic. If you can't figure it out in 10 minutes or less, move to direct SQL.
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.
You can see below some of the Hibernate documentation on criteria queries.
A criteria builder object can be requested from our Base ORM services or a virtual service or an ActiveEntity, which will bind itself automatically to the requested entity, by calling on the newCriteria()
method. The corresponding class is: cborm.models.CriteriaBuilder
newCriteria()
The arguments for the newCriteria()
method are:
Argument | Type | Required | Default | Description |
---|
If you call newCriteria()
from a virtual service layer or Active Entity, then you don't pass the entityName
argument as it roots itself automatically.
This criteria object will then be used to add restrictions to build up the exact query you want. Restrictions are basically your where statements in SQL and they build on each other via ANDs by default. For example, only retrieve products with a price over $30 or give me only active users.
Tip: Every restriction can also be negated by using the not
prefix before each method: notEq(), notIn(), notIsNull()
cache()
- Enable caching of this query result, provided query caching is enabled for the underlying session factory.
cacheRegion()
- Set the name of the cache region to use for query result caching.
comment()
- Add a comment to the generated SQL.
fetchSize()
- Set a fetch size for the underlying JDBC query.
firstResult()
- Set the first result to be retrieved or the offset integer
maxResults()
- Set a limit upon the number of objects to be retrieved.
order()
- Add an ordering to the result set, you can add as many as you like
queryHint()
- Add a DB query hint to the SQL. These differ from JPA's QueryHint, which is specific to the JPA implementation and ignores DB vendor-specific hints. Instead, these are intended solely for the vendor-specific hints, such as Oracle's optimizers. Multiple query hints are supported; the Dialect will determine concatenation and placement.
readOnly()
- Set the read-only/modifiable mode for entities and proxies loaded by this Criteria, defaults to readOnly=true
timeout()
- Set a timeout for the underlying JDBC query in milliseconds.
You can also tell Hibernate to transform the results to other formats for you once you retrieve them.
asDistinct()
- Applies a result transformer of DISTINCT_ROOT_ENTITY
asStruct()
- Applies a result transformer of ALIAS_TO_ENTITY_MAP so you get an array of structs instead of array of objects
asStream()
- Get the results as a CBstream
Now that the criteria builder object has all the restrictions and modifiers attached when can execute the SQL. Please note that you can store a criteria builder object if you wanted to. It is lazy evaluated, it just represents your SQL. It will only execute when you need it to execute via the following finalizer methods:
list()
- Execute the criteria queries you have defined and return the results as an array of objects
get( [properties] )
- Convenience method to return a single instance that matches the built up criterias query, or null if the query returns no results.
getOrFail( [properties] )
- Convenience method to return a single instance that matches the built up criterias query, or throws an exception if the query returns no results
count()
- Get the record count using hibernate projections for the given criterias
There are several methods available to you in the criteria objects to give you the actual SQL or HQL to execute, even with bindings. These are a true life-saver.
logSQL( label )
- Allows for one-off sql logging at any point in the process of building up CriteriaBuilder; will log the SQL state at the time of the call
getSQL( returnExecutableSql = false, formatSql )
- Returns the SQL string that will be prepared for the criteria object at the time of request. If you set returnExecutableSql to true , the SQL returned will include the parameters populated.
getPositionalSQLParameters()
- Returns a formatted array of parameter value and types
getSqlLog()
- Retrieves the SQL Log
startSqlLog()
- Triggers CriteriaBuilder to start internally logging the state of SQL at each iterative build
stopSqlLog()
- Stop the internal logging.
logSql()
- Allows for one-off sql logging at any point in the process of building up CriteriaBuilder; will log the SQL state at the time of the call
canLogSql()
- Returns whether or not CriteriaBuilder is currently configured to log SQL
peek( function/closure )
- Used to peek into the criteria builder process. You pass in a closure/lambda that receives the criteria. You can then use it to peek into the sql or more.
Then we get to the last two arguments: asQuery, asStream
. By default the list()
method will return an array of objects. However, if you want different results you can use this two modifiers to give you a ColdFusion query or a .
Adobe ColdFusion may throw an "Invalid CFML construct" error for certain CBORM methods that match , such as .and()
, .or()
, and .eq()
. You can use .$and()
, .$or()
, and .isEq()
to avoid these errors and build cross-engine compatible code.
The best place to see all of the functionality of the Criteria Builder is to check out the latest .
We provide you with tons of available and if none of those match what you need, you can even use a-la-carte SQL restrictions, in which you can just use SQL even with parameters. You can also do OR statements or embedded ANDs, etc.
You can also use your restrictions on the associated entity data. This is achieved via the methods section.
You can also add for the execution of the query. This can be sorting, timeouts, join types and so much more.
Method
Description
cache(boolean cache=true, cacheRegion)
Tells Hibernate whether to cache the query or not (if the query cache is enabled), and optionally choose a cache region
cacheRegion(cacheRegion)
Tells Hibernate the cache region to store the query under
comment(comment)
Add a comment to the generated SQL.
fetchSize(numeric fetchSize)
Set's the fetch size of the underlying JDBC query
firstResult(numeric firstResult)
Specifies the offset for the results. A value of 0 will return all records up to the maximum specified.
maxResults(numeric maxResults)
Set a limit upon the number of objects to be retrieved.
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
peek( target )
Peek into the criteria build process with your own closure that accepts the criteria itself.
queryHint(hint)
Add a DB query hint to the SQL. These differ from JPA's QueryHint, which is specific to the JPA implementation and ignores DB vendor-specific hints. Instead, these are intended solely for the vendor-specific hints, such as Oracle's optimizers. Multiple query hints are supported; the Dialect will determine concatenation and placement.
readOnly(boolean readOnly)
Set the read-only/modifiable mode for entities and proxies loaded by this Criteria, defaults to readOnly=true
timeout(numeric timeout)
Set a timeout for the underlying JDBC query in milliseconds.
when( test, target )
A nice functional method to allow you to pass a boolean evaulation and if true, the target closure will be executed for you, which will pass in the criteria object to it.
Method | Description |
| Note, count() can't be called on a criteria after list() has been executed. |
| Get a single entity. If you pass in the |
| Convenience method to return a single instance that matches the built up criterias query, or throws an exception if the query returns no results |
| Execute the criterias and give you the results. |
| string | true | --- | The name of the entity to bind this criteria builder with, the initial pivot. |
| boolean | false | false | To allow for query caching of list() operations |
| string | false |
| The name of the cache region to use |
| string | false | System Default | The datasource to bind the criteria query on, defaults to the one in this ORM service |
Hibernate also supports the ability to work with sql projections and sql aggregates. Instead of treating the results as an array of objects or a stream of objects you can return the result as a row with columns of data.
This is great for API driven applications as you DON"T have to retrieve the entire object graphs, you can decide which columns to bring back and return an array of structs with lightening speed by just using the asStruct()
modifier.
There are several projection types you can use which are great for doing counts, distinct counts, max values, sums, averages and much more.
The method in the criteria builder that will allow you to add projections is called withProjections()
. You will then use it's arguments to tell Hibernate what projection or aggregates to compile into the query. Here is the method signature:
Below are the available projections you can use from this method
The value of the arguments 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.
If the :alias
is not used, then the alias becomes the property name.
Here is a detail overview of each projection type.
The name of the property to average or a list or array of property names to average on
The name of the property to count on or a list or array of property names to count on
Get a distinct count on a property or list of properties
Distinct is used to return only distinct (different) values from a property or list of properties
Which properties to group in the SQL statement.
Return an array of IDs of the current projected entity. Let's say we want all the user id's that have never logged in to the system. So we can use that to send them mails.
Return a max() sql projection on a a property or list of properties
Return a min() sql projection on a a property or list of properties
Return or a list of properties in the projection. Basically pick and choose in the select statement. The cool thing is that this can be a property or a full relationship, which can give you an array of properties and objects.
You can navigate relationships using the dot
notation.
Run a count( * )
on the projection alongside other projections.
Run a sql sum() on a one or many properties
Do a projection based on arbitrary SQL and SQL grouping strings. The value can be a single struct or an array of structs with the following pattern:
sql
- The raw sql to execute
alias
- The aliases to apply
property
- The property projected on
group
- What to group on if needed
This will produce the following SQL
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")
id
Return the projected identifier value
withProjections(id=true)
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")
rowCount
Do a row count on the criteria
withProjections(rowcount=true)
sum
The name of the property to sum or a list or array of property names
withProjections(sum="balance")
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