////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

A derived property is one that takes its value from a SQL expression, often but not necessarily based on the value of one or more other persistent properties.  Consider a Product class like this:

[source,java]
----
class Product {
    Float price
    Float taxRate
    Float tax
}
----

If the `tax` property is derived based on the value of `price` and `taxRate` properties then is probably no need to persist the `tax` property.  The SQL used to derive the value of a derived property may be expressed in the ORM DSL like this:

[source,java]
----
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:

[source,groovy]
----
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 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:

[source,java]
----
Product.findAllByTaxGreaterThan(21.12)
----

Derived properties may be referenced in the Criteria API:

[source,java]
----
Product.withCriteria {
    gt 'tax', 21.12f
}
----

The SQL that is generated to support either of those would look something like this:

[source,groovy]
----
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: 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.
