Monday, March 7, 2011

Hibernate Annotation Many-to-Many

Realizing the relations between entity is a tedious part in hibernate. Here i will explain a Many-to-Many relationship using hibernate annotations with an example.

Lets consider a relation between Product and Category. A product can belong to any number of categories and category can have many products. Hence relation between Product and Category is Many-to-Many.

In the database, Many-to-Many is realized by using an intersection table holding product_id and category_id as foreign keys to corresponding tables.







In hibernate, product and category are considered as entities and product_category_ix is used as joining table to realize Many-to-Many.

Product.java
package com.jb.data;

import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

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

    private long id;
    private String name;
    private Set categories;

    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="product_id")
    public long getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="product_category_ix", joinColumns={@JoinColumn(name="product_id")},
        inverseJoinColumns={@JoinColumn(name="category_id")})
    public Set getCategories() {
        return categories;
    }

    public void setCategories(Set categories) {
        this.categories = categories;
    }
    
}



Category.java
package com.jb.data;

import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="category")
public class Category {

    private long id;
    private String name;
    private Set products;

    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="category_id")
    public long getId() {
        return id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="product_category_ix",
        joinColumns={@JoinColumn(name="category_id")},
        inverseJoinColumns={@JoinColumn(name="product_id")})
    public Set getProducts() {
        return products;
    }

    public void setProducts(Set products) {
        this.products = products;
    }
    
}


HibernateUtil.java
package com.jb.util;

import com.jb.data.Category;
import com.jb.data.Lead;
import com.jb.data.Product;
import com.jb.data.contactList;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    private static Session session;
    static {
        try {

                AnnotationConfiguration configuration = new AnnotationConfiguration();
                configuration.addAnnotatedClass(contactList.class);
                configuration.addAnnotatedClass(Lead.class);
                configuration.addAnnotatedClass(Product.class);
                configuration.addAnnotatedClass(Category.class);
                configuration.configure();
                                        
                sessionFactory = configuration.buildSessionFactory();

        } catch (Throwable ex) {
                System.err.println("Initial SessionFactory creation failed." + ex);
                throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
            return sessionFactory;
    }

    public static Session getSession() {
        session = getSessionFactory().openSession();
        
        return session;
    }


ProductService.java
package com.jb.service;

import com.jb.dao.CategoryDao;
import com.jb.dao.ProductDao;
import com.jb.data.Category;
import com.jb.data.Product;
import java.util.LinkedHashSet;
import java.util.Set;

public class ProductService {

    public List getCategories(){

        List categories = new ArrayList();
        
        Set products = new LinkedHashSet();

        Product epson = new Product();
        epson.setName("EPSON");
        products.add(epson);

        Product hp = new Product();
        hp.setName("HP");
        products.add(hp);

        Category category = new Category();
        category.setName("Laser Printer");
        category.setProducts(products);
        categories.add(category);

        category = new Category();
        category.setName("Ink Jet Printer");
        category.setProducts(products);
        categories.add(category);
        
        return categories;
    }
    
    public static void main(String[] arg){
        System.out.println("processing main...");

        ProductService productService = new ProductService();
        List categories = productService.getCategories();
        CategoryDao categoryDao = new CategoryDao();
        categoryDao.saveCategories(categories);

        System.out.println("Done..!");
    }
} 


CategoryDao.java
package com.jb.dao;

import com.jb.data.Category;
import com.jb.util.HibernateUtil;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class CategoryDao {

    public void saveCategory(Category category) {
       System.out.println("save...");
       Session session = HibernateUtil.getSession();
       Transaction transaction = session.beginTransaction();
       session.save(category);
       transaction.commit();
    }

    public void saveCategories(List categories) {

       System.out.println("save...");
       Session session = HibernateUtil.getSession();
       Transaction transaction = session.beginTransaction();
        for (Category category : categories) {
            session.save(category);
        }
       transaction.commit();
    }
}
After running main program, db tables (category, product and product_category_ix) will be updated with new entries.

category:







product:







product_category_ix:


No comments:

Post a Comment