openxava / documentation / Lesson 10: Calculated properties

Course: 1. Getting started | 2. Basic domain model (1) | 3. Basic domain model (2) | 4. Refining the user interface | 5. Agile development6. Mapped superclass inheritance | 7. Entity inheritance | 8. View inheritance | 9. Java properties | 10. Calculated properties | 11. @DefaultValueCalculator in collections | 12. @Calculation and collections totals | 13. @DefaultValueCalculator from file | 14. Manual schema evolution | 15. Multi user default value calculation | 16. Synchronize persistent and computed properties | 17. Logic from database  | 18. Validating with @EntityValidator 19. Validation alternatives  | 20. Validation on remove  21. Custom Bean Validation annotation  | 22. REST service call from validation  | 23. Attributes in annotations  | 24. Refining the standard behavior | 25. Behavior & business logic | 26. References & collections | A. Architecture & philosophy | B. Java Persistence API | C. Annotations | D. Automated testing

Table of contents

Lesson 10: Calculated properties
Calculated properties
Simple calculated property
We have established business logic by creating getters and setters, we have seen the use of the Lombok library and its applicability, we will now see how to apply other types of properties to our application.

If you don't like videos follow the instructions below.

Calculated properties

Perhaps the most simple business logic you can add to your application is a calculated property. The properties you have used until now are persistent, i.e., each property is stored in a column in a table in the database. A calculated property is a property that does not store its value in the database but it's calculated any time the property is accessed. See the difference between a persistent and a calculated property.
// Persistent property
@Getter @Setter // Has getter and setter
int quantity; // Has a field, so it's persistent
// Calculated property
public int getAmount() { // It has no field and no setter, only a getter
    return quantity * price; // with a calculation
Calculated properties are automatically recognized by OpenXava. You can use them in views, tabular lists or any other part of your code.
We are going to use calculated properties to add the money element to our invoicing application. Because, we have details, products, quantities. But what about amounts?

Simple calculated property

The first step will be to add an amount property to the Detail. We want the detail amount to be recalculated and shown to the user when the user chooses a product and type in the quantity:
Adding this feature to your current code is practically adding a calculated property to Detail. Just add the next code to the Detail class:
@Depends("product.number, quantity")  // When the user changes product or quantity
public BigDecimal getAmount() { // this property is recalculated and redisplayed
    if (product == null || product.getPrice() == null) return BigDecimal.ZERO;
    return new BigDecimal(quantity).multiply(product.getPrice()); 
Simply put the calculation in getAmount() and use @Depends to indicate to OpenXava that the amount property depends on product.number and quantity, thus each time the user changes any of these values the property will be recalculated. Note as we in this case we use product instead of getProduct() and quantity instead of getQuantity() because from inside the class you can access directly to its fields.
Now you have to add this new property to the details collection of CommercialDocument:
@ListProperties("product.number, product.description, quantity, amount") // amount added
Collection<Detail> details;
Nothing else is required. The mere addition of the getter and modifying the list properties is enough. Try the Invoice and Order modules to see the amount property in action.


In this lesson you have learned the application of calculated properties, and their differences from persistent properties, when establishing business logic. In future lessons we will see how to work with collections and totals.

Download source code of this lesson

Any problem with this lesson? Ask in the forum Everything fine? Go to Lesson 11