Class QueryUtil
entityUtil instead unless a developer has explicitly
told you to use this.
These go straight to the persistence layer, so everything the mapping layer does on the way out is skipped. Dynamic calculated fields are never computed, and the read is not tracked the way a normal entity fetch is. What comes back can look like the entity and quietly not be it, which is a harder failure to spot than an error would be.
They also return untyped rows rather than entities, so the caller unpacks positional values and the rest of the configuration cannot treat the result as an entity. And the query string names entities and fields directly, which binds the configuration to the data model: a later model change breaks a script that nothing in the build can see.
entityUtil.searchEntity(...), entityUtil.findEntity(...) and
entityUtil.getEntity(...) answer nearly every read a script or expression needs, and
they hand back entities rather than rows. Reach for this only when someone has decided a query
genuinely cannot be expressed that way - an aggregate, or a join no search covers - and has
said so.
For writes see updateUtil, which carries the same warning and a heavier one: bulk
statements bypass the write side of the entity lifecycle entirely.
-
Constructor Summary
ConstructorsConstructorDescriptionQueryUtil(jakarta.persistence.EntityManager entityManager, com.ssgllc.fish.service.GenericQueryService genericQueryService) -
Method Summary
Modifier and TypeMethodDescriptionstatic jakarta.persistence.EntityManagerLast resort, and the sharpest one here: hands out the rawEntityManager.Last resort: runs an HQL query and returns untyped rows; preferentityUtil.searchEntity(...).queryListLimit(String queryStr, Integer limit) Last resort: runs an HQL query with a row limit; preferentityUtil.searchEntity(...).queryListLimitPage(String queryStr, Integer limit, Integer pageNumber) Last resort: runs a paged HQL query with a row limit; preferentityUtil.searchEntity(...).queryListParam(String queryStr, Map<String, Object> params) Last resort: runs a parameterised HQL query; preferentityUtil.searchEntity(...).Last resort: runs a parameterised HQL query with a row limit; preferentityUtil.searchEntity(...).queryListParamLimitPage(String queryStr, Map<String, Object> params, Integer limit, Integer pageNumber) Last resort: runs a parameterised, paged HQL query; preferentityUtil.searchEntity(...).queryListParamLimitPageSkipLocked(String queryStr, Map<String, Object> params, Integer limit, Integer pageNumber) Executes an HQL query with named parameters, pagination, and skip-locked pessimistic locking, returning the result as a list of objects.
This method ensures that rows currently locked by other transactions are skipped to avoid blocking.static ObjectquerySingle(String queryStr) Last resort: runs an HQL query for one row; preferentityUtil.findEntity(...).static ObjectquerySingleParam(String queryStr, Map<String, Object> params) Last resort: runs a parameterised HQL query for one row; preferentityUtil.findEntity(...).static StringsqlLiteral(Object value) Quotes a value so it can be written into a query as a single value.
Use this on anything a user typed, such as a cell of a report's table parameter.
-
Constructor Details
-
QueryUtil
public QueryUtil(jakarta.persistence.EntityManager entityManager, com.ssgllc.fish.service.GenericQueryService genericQueryService)
-
-
Method Details
-
queryList
Last resort: runs an HQL query and returns untyped rows; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). It returns entities with calculated fields computed and the read tracked, rather than untyped rows straight from the persistence layer. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.- Returns:
- A list of query results.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryList("select f.id from FieldConfig f")
-
queryListLimit
Last resort: runs an HQL query with a row limit; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). It takes a page size directly and returns entities. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.limit- The maximum number of results to return.- Returns:
- A list of query results, limited to the specified number.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryListLimit("select f.id from FieldConfig f", 5)
-
queryListLimitPage
public static List<Object> queryListLimitPage(String queryStr, Integer limit, Integer pageNumber) throws Exception Last resort: runs a paged HQL query with a row limit; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). It pages natively and returns entities. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.limit- The maximum number of results per page.pageNumber- The zero-based page number to retrieve.- Returns:
- A list of query results for the specified page, limited to the given number of results.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryListLimitPage("select f.id from FieldConfig f", 5, 1)
-
queryListParam
public static List<Object> queryListParam(String queryStr, Map<String, Object> params) throws ExceptionLast resort: runs a parameterised HQL query; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). Its search-field map expresses most parameterised lookups without a query string. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.params- A map of named parameters to be set in the query.- Returns:
- A list of query results.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryListParam("select f.id from FieldConfig f where f.name = :name", [name: "title"])
-
queryListParamLimit
public static List<Object> queryListParamLimit(String queryStr, Map<String, Object> params, Integer limit) throws ExceptionLast resort: runs a parameterised HQL query with a row limit; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). Its search-field map plus a page size covers most parameterised lookups. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.params- A map of named parameters to be set in the query.limit- The maximum number of results to return.- Returns:
- A list of query results, limited to the specified number.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryListParamLimit("select f.id from FieldConfig f where f.createdDate > :date", [date: dateUtil.startOfToday()], 10)
-
queryListParamLimitPage
public static List<Object> queryListParamLimitPage(String queryStr, Map<String, Object> params, Integer limit, Integer pageNumber) throws ExceptionLast resort: runs a parameterised, paged HQL query; preferentityUtil.searchEntity(...).
Prefer
entityUtil.searchEntity(...). It covers parameterised, paged lookups and returns entities. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.params- A map of named parameters to be set in the query.limit- The maximum number of results per page.pageNumber- The zero-based page number to retrieve.- Returns:
- A list of query results for the specified page, limited to the given number of results.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
return queryUtil.queryListParamLimitPage("select f.id from FieldConfig f where f.createdDate > :date", [date: dateUtil.startOfToday()], 10, 2)
-
queryListParamLimitPageSkipLocked
public static List<Object> queryListParamLimitPageSkipLocked(String queryStr, Map<String, Object> params, Integer limit, Integer pageNumber) throws ExceptionExecutes an HQL query with named parameters, pagination, and skip-locked pessimistic locking, returning the result as a list of objects.
This method ensures that rows currently locked by other transactions are skipped to avoid blocking.
Prefer
entityUtil.searchEntity(...). Row-level lock skipping is a queue-draining concern, so reach for this one only when a developer has asked for exactly that.- Parameters:
queryStr- The HQL query string to execute.params- A map of named parameters to be set in the query.limit- The maximum number of results per page.pageNumber- The zero-based page number to retrieve.- Returns:
- A list of query results for the specified page, limited to the given number of results, skipping any locked rows.
- Throws:
Exception- If an error occurs while executing the query.
Groovy example:
def params = [:] params.calcTypeId = stringUtil.uuidFromString(conceptUtil.getConceptIdFromCode('CalculationType', 'CALC_DYNAMIC')) return queryUtil.queryListParamLimitPageSkipLocked("select f.id from FieldConfig f where f.calcType.id = :calcTypeId", params, 20, 0)
Returns:
A list of FieldConfig IDs with calcType of "CALC_DYNAMIC", up to 20 results, skipping locked rows.Note: This method uses pessimistic locking with SKIP_LOCKED, which ensures that locked rows are not included in the result set. Also, any rows that are joined will be locked, so be careful with things like not locking concept table rows.
-
querySingle
Last resort: runs an HQL query for one row; preferentityUtil.findEntity(...).
Prefer
entityUtil.findEntity(...). It looks a single entity up by field value and returns the entity. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.- Returns:
- A single query result, or null if no result is found.
- Throws:
Exception- If an error occurs while executing the query including finding more than one result.
Groovy example:
return queryUtil.querySingle("select f.id from FieldConfig f where f.name = 'deduplicationEnabled'")
-
querySingleParam
Last resort: runs a parameterised HQL query for one row; preferentityUtil.findEntity(...).
Prefer
entityUtil.findEntity(...). It looks a single entity up by field value without a query string. Use this only when a developer has said a raw query is needed.- Parameters:
queryStr- The HQL query string to execute.params- A map of named parameters to be set in the query.- Returns:
- A single query result, or null if no result is found.
- Throws:
Exception- If an error occurs while executing the query including finding more than one result.
Groovy example:
return queryUtil.querySingleParam("select f.id from FieldConfig f where f.name = :name", [name: "deduplicationEnabled"])
-
getEntityManager
public static jakarta.persistence.EntityManager getEntityManager()Last resort, and the sharpest one here: hands out the rawEntityManager.
Use only when a developer has explicitly directed you to, and with care. Everything the mapping layer does is bypassed - dynamic calculated fields are not computed and reads are not tracked - and nothing bounds what a caller can do with it, including writes that skip the entity lifecycle. Prefer
entityUtilfor reading and writing entities, and the query methods on this class if a raw read is genuinely required.- Returns:
- The EntityManager instance.
Groovy example:
return queryUtil.getEntityManager()
-
sqlLiteral
Quotes a value so it can be written into a query as a single value.
Use this on anything a user typed, such as a cell of a report's table parameter. A value containing a quote character otherwise ends the quoted text early, and the rest of it is read as part of the query instead of as data - which is how someone changes what a query does by typing into a form. Numbers are written as they are; everything else is handed to the database's own rule for writing a value, so how a quote inside the value is escaped is the database's business rather than something Casetivity decides.
An empty value is written asnull, which every database understands as a value in its own right. Be aware that null is not equal to anything, including itself, so a comparison against it is neither true nor false and a row with nothing in that column is not returned. Where that is not what you want, writeis nullinstead of comparing.
Anything that is not text, a number, or empty is rejected rather than written into the query as whatever it happens to look like when printed.- Parameters:
value- The value to quote. Text, a number, or empty; anything else, such as a whole row of a table parameter, is rejected - pick the single field you meant out of it first.- Returns:
- The value, ready to be written into a query.
Groovy example:
return "DISEASE_NAME = " + queryUtil.sqlLiteral("Hansen's disease")
Returns:
DISEASE_NAME = 'Hansen''s disease'
SpEL example:
#sqlLiteral(42)
Returns:
42
-