Object-Relational Mapping
ods. It uses Groovy’s dynamic capabilities to add finder methods to domain classes. For example, an application can find accounts with low balances, as shown in figure 5A. Provided that the method name follows certain naming conventions, the missingMethod()/ExpandoMetaClass mechanism intercepts the call to the method and defines a method that parses the method name to build a query and executes it.
GORM dynamic finders support a rich query language. Finder method names can use comparison operators such as equals, less than, and greater than. They can also use the and, or, and not logical operators. Even though the query language is limited to the properties of a single class—no joins—many queries can be expressed as dynamic finders. A GORM application contains much less data-access code and has far fewer explicit dependencies on the Hibernate framework. In addition, because the finder methods are readily available on the domain classes, GORM avoids the problem of needing to resolve inter-component references.
One potential drawback of these finder methods is that the method name is the definition of the query. It’s not always possible to define an intentional revealing name for a query that encapsulates the actual implementation. As a result, evolving business requirements can cause the names of finder methods to change, which increases the cost of maintaining the application.
method, which GORM injects into each domain class. It takes an HQL query and a list of parameters as arguments.
One nice feature of this API is that it allows an application to execute an HQL query without explicitly invoking the Hibernate API. The application does not have to solve the problem of obtaining a reference to a DAO or other component. One drawback, however, is that knowledge of HQL is hardwired into the application.
The other option, which is especially useful when constructing queries dynamically, is to use GORM criteria queries, which wrap the Hibernate Criteria API described earlier. As with the other APIs, GORM dynamically injects a createCriteria() method into domain classes. This method allows an application to construct and execute a query without having an explicit dependency on the Hibernate API.
Figure 5C is the GORM criteria query version of the query that retrieves accounts with low balances. The createCriteria() method returns an object for building queries. The application executes the query by calling list(), which takes a Groovy closure as an argument and returns a list of matching objects. The closure argument contains method calls such as lt() that add restrictions to the query.
Applications can use these APIs to execute queries that are not supported by dynamic finders. One potential downside, which could be considered to be a weakness of GORM, is the potential lack of modularity and violation of the Separation of Concerns principle. There is a risk of scattering the data-access operations for a domain class throughout the application. Some data-access methods are defined by the domain class, but the rest are intermingled with the application’s business logic, which could be
d e faccounts=Account.findAllByBalanceLessThan(threshold)
A
WHEN DYNAMIC FINDERS
ARE INSUFFICIENT
For applications that need
to execute more elaborate
queries, GORM provides a
couple of different options.
An application can execute
HQL queries directly. For
example, an application
can execute an HQL query
to retrieve accounts with
low balances, as shown in
figure 5B. This code snip-
pet invokes the findAll()
B
L ist accounts = Account.findAll(“from Account where balance < ?”, [threshold])
C
def c = Account.createCriteria() def results = c.list {
lt(“balance”, threshold)
}
References:
Archives