A derived property is a property that takes its value from a SQL expression,
often but not necessarily based on the value of some other persistent
property. Consider a Product class like this:
class Product {
Float price
Float taxRate
Float tax
}
If the
tax
property is derived based on the value of
price
and
taxRate
properties then there may be no need to persist the
tax
property in the
database. The SQL used to derive the value of a derived property may be
expressed in the ORM DSL like this:
class Product {
Float price
Float taxRate
Float tax static mapping = {
tax formula: 'PRICE * TAX_RATE'
}
}
Note that the formula expressed in the ORM DSL is SQL so references to other
properties should relate to the persistence model not the object model, which
is why the example refers to
PRICE
and
TAX_RATE
instead of
price
and
taxRate
.
With that in place, when a Product is retrieved with something like
Product.get(42)
, the SQL that is generated to support
that will look something like this:
select
product0_.id as id1_0_,
product0_.version as version1_0_,
product0_.price as price1_0_,
product0_.tax_rate as tax4_1_0_,
product0_.PRICE * product0_.TAX_RATE as formula1_0_
from
product product0_
where
product0_.id=?
Since the
tax
property is being derived at runtime and not stored in the
database it might seem that the same effect could be achieved by adding
a method like
getTax()
to the
Product
class that simply returns the
product of the
taxRate
and
price
properties. With an approach like
that you would give up the ability query the database based on the value
of the
tax
property. Using a derived property allows exactly that. To
retrieve all
Product
objects that have a
tax
value greater than 21.12
you could execute a query like this:
Product.findAllByTaxGreaterThan(21.12)
Derived properties may be referenced in the Criteria API:
Product.withCriteria {
gt 'tax', 21.12f
}
The SQL that is generated to support either of those would look something like this:
select
this_.id as id1_0_,
this_.version as version1_0_,
this_.price as price1_0_,
this_.tax_rate as tax4_1_0_,
this_.PRICE * this_.TAX_RATE as formula1_0_
from
product this_
where
this_.PRICE * this_.TAX_RATE>?
Note that because the value of a derived property is generated in the database and depends
on the execution of SQL code, derived properties may not have GORM constraints applied
to them. If constraints are specified for a derived property, they will be ignored.