✅ Short Answer
The @Formula
annotation lets you map a read-only calculated property in an entity by defining a SQL expression → Hibernate includes it in the SELECT
statement when loading the entity.
🔎 Detailed Explanation
🔹 @Formula
allows you to expose virtual properties — values not stored as fields in the entity’s table but computed dynamically using SQL.
🔹 The SQL expression you provide in @Formula
is inlined into the entity’s SELECT query → it can use:
✅ Columns from the same table.
✅ SQL functions.
✅ Even subqueries.
🔹 Simple Example
@Entity
public class Order {
@Id
private Long id;
private double price;
private double tax;
@Formula("price + tax") // computed in SQL SELECT
private double total;
}
What happens?
When Hibernate loads an Order
, it generates:
select id, price, tax, (price + tax) as total from order ...
✅ The total
field in Java is populated automatically with the result of the formula.
🔹 Advanced Example: Subquery
Compute a customer’s order count:
@Entity
public class Customer {
@Id
private Long id;
@Formula("(select count(o.id) from orders o where o.customer_id = id)")
private int orderCount;
}
✅ This gives a read-only field with the number of orders per customer, without a join.
🔹 Important notes
✅ The @Formula
value is read-only → you can’t persist changes to it.
✅ The SQL expression must be valid for your database dialect.
❌ Since it’s evaluated by the database, portability may suffer if you use DB-specific SQL functions.
📊 When to use @Formula
✅ Calculated fields based on other columns in the same entity.
✅ Aggregations or subqueries (counts, sums) for convenience without additional queries.
✅ Mapping denormalized or derived data when refactoring is impossible.
📌 Key Takeaways
✅ @Formula
lets you map calculated read-only properties using SQL expressions evaluated in Hibernate’s SELECT
.
✅ Great for dynamic, computed fields → reduces need for post-processing in Java.
✅ Be careful with database portability, since formulas use native SQL syntax.