0
Sponsored Links


Ad by Google
We all know Hibernate is very popular ORM framework and nowadays on very demanding. Hibernate has various features and their advantages like Hibernate Criteria Query, Second Level Cache, Fetching Strategy etc.
So you must have to be a very good in Hibernate and practical experienced in Hibernate.
 In this post, I am going to show you how to use Hibernate's one  hidden key called Formula. So this tutorial is about @Formula annotation and their uses. Hibernate's formula annotation uses also known as calculated property or derived properties. Formula annotation is used to calculate the value of different properties, sometimes you may need to calculate the value based on two different columns value fetched in a query.
For example you have a column called price and vat and you want to calculate the total price  including price and vat, but you don't have the total price column in your table the value of total price will be calculated at run time using these tow properties in HQL expression.

In this tutorial, I am using a product table and fetching their total price using formula annotation below is the table structure used in this tutorial. For creating a step by step hibernate project you can follow my one-to-many-association example in hibernate which help you to create step by step project.
Step 1. Create database and table

CREATE DATABASE /*!32312 IF NOT EXISTS*/`hibernate_tutorial`

USE `hibernate_tutorial`;

/*Table structure for table `product` */

DROP TABLE IF EXISTS `product`;

CREATE TABLE `product` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `manufactured_date` datetime DEFAULT NULL,
  `price` float DEFAULT NULL,
  `product_code` varchar(255) DEFAULT NULL,
  `product_name` varchar(255) DEFAULT NULL,
  `vat` float DEFAULT NULL,
  PRIMARY KEY (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

Step 2. Create Product pojo/entity annotated class.
Class : Product.java
package com.javamakeuse.hibernate.poc.pojo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Formula;

@Entity
@Table(name = "product")
public class Product {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "product_id")
	private int id;

	@Column(name = "product_code")
	private String productCode;

	@Column(name = "product_name")
	private String productName;

	@Column(name = "price")
	private float price;

	@Column(name = "vat")
	private float vat;

	@Formula("price*10/100+price")
	private float totalPrice;

	@Column(name = "manufactured_date")
	@Temporal(TemporalType.TIMESTAMP)
	private Date manufacturedDate;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getProductCode() {
		return productCode;
	}

	public void setProductCode(String productCode) {
		this.productCode = productCode;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	public float getVat() {
		return vat;
	}

	public void setVat(float vat) {
		this.vat = vat;
	}

	public float getTotalPrice() {
		return totalPrice;
	}

	public void setTotalPrice(float totalPrice) {
		this.totalPrice = totalPrice;
	}

	public Date getManufacturedDate() {
		return manufacturedDate;
	}

	public void setManufacturedDate(Date manufacturedDate) {
		this.manufacturedDate = manufacturedDate;
	}

	@Override
	public String toString() {
		return "Product [id=" + id + ", productCode=" + productCode
				+ ", productName=" + productName + ", price=" + price
				+ ", vat=" + vat + ", totalPrice=" + totalPrice
				+ ", manufacturedDate=" + manufacturedDate + "]";
	}

}

In Product class we used @Formula annotation on read only property totalPrice

totalPrice property is not in table, It's a calculated property, the value of this property will calculated at run time with the help of price and vat property. It will calculate the total price of the product.

Step 3. Create HibernateUtility.java class to build SessionFactory.

package com.javamakeuse.hibernate.poc.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtility {
	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		Configuration configuration = new Configuration();
		configuration.configure();

		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).build();
		SessionFactory sessionFactory = configuration
				.buildSessionFactory(serviceRegistry);

		return sessionFactory;
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

}

Step 4. Create hibernate.cfg.xml file to defined mapping class and database related configuration.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate_tutorial</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
         
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <!-- <property name="format_sql">true</property> -->
        <mapping class="com.javamakeuse.hibernate.poc.pojo.Product"/>
          
    </session-factory>
</hibernate-configuration>

Step 5. Create ProductService class to fetch the product details.

package com.javamakeuse.hibernate.poc.service;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.javamakeuse.hibernate.poc.pojo.Product;
import com.javamakeuse.hibernate.poc.util.HibernateUtility;

public class ProductService {

	public static Product getProduct(int productId) {
		SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
		Session session = sessionFactory.openSession();
		return (Product) session.get(Product.class, productId);
	}

	public static void main(String[] args) {
		System.out.println(getProduct(1));
	}
}

Run it, It will print the calculated total price.
OUT PUT:
Hibernate: select product0_.product_id as product_1_0_0_, product0_.manufactured_date as manufact2_0_0_, product0_.price as price3_0_0_, product0_.product_code as product_4_0_0_, product0_.product_name as product_5_0_0_, product0_.vat as vat6_0_0_, product0_.price*10/100+product0_.price as formula0_0_ from product product0_ where product0_.product_id=?
Product [id=1, productCode=TP001, productName=Tooth Paste, price=100.0, vat=10.0, totalPrice=110.0, manufacturedDate=2015-01-01 00:05:00]

Note: you can use formula annotation as more complex way, like to getting old manufactured date of product you can use below syntax in Product.java class
@Formula("(select min(p.manufactured_date) from Product p where p.product_id = product_id)")
private Date oldProductDate;

You can download the complete source code from here

That's it :)
Sponsored Links

0 comments:

Post a Comment