Fetch Data using Many To Many Relationship in Hibernate 5


Copy JAR files which are listed below:

antlr-2.7.7.jar
classmate-1.3.4.jar
commons-lang3-3.6.jar
commons-logging-1.1.3.jar
dom4j-1.6.1.jar
ehcache-core-2.6.11.jar
geolatte-geom-1.1.0.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.2.11.Final.jar
hibernate-ehcache-5.2.12.Final.jar
hibernate-ejb3-persistence.jar
hibernate-enhance-maven-plugin-4.3.7.Final.jar
hibernate-entitymanager.jar
hibernate-java8-5.2.11.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-spatial-5.2.11.Final.jar
hibernate-validator-6.0.2.Final.jar
javassist-3.16.1-GA.jar
jboss-logging-3.3.1.Final.jar
jboss-transaction-api_1.1_spec-1.0.1.Final.jar
jts-1.11.jar
mysql-connector-java-5.1.36.jar
slf4j-api-1.7.21.jar




Create a database with the name is hibernate5. This database have 3 tables: Category table, Product table and Category_Product table. Category table and Product table have a Many to Many. One category can have many products and One product can have many categories.

--
-- Table structure for table `category`
--

CREATE TABLE `category` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(250) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `category`
--

INSERT INTO `category` (`name`) VALUES('Category 1');
INSERT INTO `category` (`name`) VALUES('Category 2');
INSERT INTO `category` (`name`) VALUES('Category 3');
INSERT INTO `category` (`name`) VALUES('Category 4');

--
-- Table structure for table `product`
--

CREATE TABLE `product` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  `price` decimal(10,2) NOT NULL,
  `quantity` int(11) NOT NULL,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `active` tinyint(1) NOT NULL,
  `creationDate` date NOT NULL,
  `categoryId` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `product`
--

INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Laptop 2', '1000.00', 2, 'good', 1, '2016-06-10', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Laptop 3', '200.00', 5, 'good', 1, '2015-06-15', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Laptop 4', '500.00', 8, 'good', 0, '2015-06-24', 1);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Computer 1', '560.00', 10, 'good', 0, '2015-02-25', 2);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Computer 2', '520.00', 4, 'good', 0, '2015-06-28', 2);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Computer 3', '720.00', 5, 'good', 1, '2015-08-25', 2);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Laptop 1', '110.00', 19, 'good', 0, '2016-07-12', 2);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Mobile 1', '222.00', 5, 'good', 1, '2015-03-16', 3);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Mobile 2', '1000.00', 4, 'good', 1, '2015-06-27', 3);
INSERT INTO `product` (`name`, `price`, `quantity`, `description`, `active`, `creationDate`, `categoryId`) VALUES('Mobile 3', '1000.00', 4, 'good', 1, '2015-06-27', 3);

--
-- Table structure for table `category_product`
--

CREATE TABLE `category_product` (
  	`category_id` int(11) NOT NULL,
  	`product_id` int(11) NOT NULL,
   	PRIMARY KEY (`category_id`,`product_id`),
	FOREIGN KEY (`category_id`) REFERENCES `category` (`id`),
	FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `category_product`
--

INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(1, 1);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(1, 2);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(1, 3);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(2, 1);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(2, 4);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(3, 1);
INSERT INTO `category_product` (`category_id`, `product_id`) VALUES(3, 7);

Structure of Category Table

Category Table

Structure of Product Table

Product Table

Structure of Category_Product Table

Category_Product Table

Create two entities classes – Category.java and Product.java, to represent the above tables

Category.java

package entities;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
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 implements java.io.Serializable {

	private Integer id;
	private String name;
	private Set<Product> products = new HashSet<Product>(0);

	public Category() {
	}

	public Category(String name) {
		this.name = name;
	}

	public Category(String name, Set<Product> products) {
		this.name = name;
		this.products = products;
	}

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "id", unique = true, nullable = false)
	public Integer getId() {
		return this.id;
	}

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

	@Column(name = "name", nullable = false, length = 250)
	public String getName() {
		return this.name;
	}

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

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "category_product", catalog = "abc", joinColumns = {
			@JoinColumn(name = "category_id", nullable = false, updatable = false) }, 	inverseJoinColumns = { @JoinColumn(name = "product_id", nullable = false, updatable = false) })
	public Set<Product> getProducts() {
		return this.products;
	}

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

}

Product.java

package entities;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "product")
public class Product implements java.io.Serializable {

	private Integer id;
	private String name;
	private BigDecimal price;
	private int quantity;
	private String description;
	private boolean active;
	private Date creationDate;
	private Set<Category> categories = new HashSet<Category>(0);

	public Product() {
	}

	public Product(String name, BigDecimal price, int quantity, String description, boolean active, Date creationDate) {
		this.name = name;
		this.price = price;
		this.quantity = quantity;
		this.description = description;
		this.active = active;
		this.creationDate = creationDate;
	}

	public Product(String name, BigDecimal price, int quantity, String description, boolean active, Date creationDate, Set<Category> categories) {
		this.name = name;
		this.price = price;
		this.quantity = quantity;
		this.description = description;
		this.active = active;
		this.creationDate = creationDate;
		this.categories = categories;
	}

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "id", unique = true, nullable = false)
	public Integer getId() {
		return this.id;
	}

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

	@Column(name = "name", nullable = false, length = 250)
	public String getName() {
		return this.name;
	}

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

	@Column(name = "price", nullable = false, precision = 10)
	public BigDecimal getPrice() {
		return this.price;
	}

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

	@Column(name = "quantity", nullable = false)
	public int getQuantity() {
		return this.quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	@Column(name = "description", nullable = false, length = 65535)
	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Column(name = "active", nullable = false)
	public boolean isActive() {
		return this.active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	@Temporal(TemporalType.DATE)
	@Column(name = "creationDate", nullable = false, length = 10)
	public Date getCreationDate() {
		return this.creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "category_product", catalog = "abc", joinColumns = {
			@JoinColumn(name = "product_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "category_id", nullable = false, updatable = false) })
	public Set<Category> getCategories() {
		return this.categories;
	}

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

}




Hibernate Configuration File

Puts Category.java and Product.java in your Hibernate configuration file, and also MySQL connection details.

<?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="hibernate.enable_lazy_load_no_trans">true</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.password">123456</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate5</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.dialect">org.hibernate.spatial.dialect.mysql.MySQLSpatialDialect</property>
		<property name="hibernate.current_session_context_class">thread</property>
		<mapping class="entities.Category" />
		<mapping class="entities.Product" />
	</session-factory>
</hibernate-configuration>

The HibernateUtil class helps in creating the SessionFactory from the Hibernate configuration file. The SessionFactory is threadsafe, so it is not necessary to obtain one for each thread.

package fetch_data;

import org.hibernate.*;
import org.hibernate.boot.*;
import org.hibernate.boot.registry.*;

public class HibernateUtil {

	private static final SessionFactory sessionFactory;

	static {
		try {
			StandardServiceRegistry standardRegistry = new
					StandardServiceRegistryBuilder()
					.configure("hibernate.cfg.xml")
					.build();
			Metadata metaData = new MetadataSources(
					standardRegistry)
					.getMetadataBuilder()
					.build();
			sessionFactory = metaData.getSessionFactoryBuilder().build();
		} catch (Throwable th) {
			throw new ExceptionInInitializerError(th);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;

	}
}

The CategoryModel class contains methods to interact with the database.

package fetch_data;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import entities.Category;

public class CategoryModel {

	private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

	public Category find(int id) {
		Category category = null;
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			org.hibernate.query.Query query = session.createQuery("from Category where id = :id");
			query.setParameter("id", id);
			category = (Category) query.uniqueResult();
			transaction.commit();
		} catch (Exception e) {
			category = null;
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			session.close();
		}
		return category;
	}

}

The ProductModel class contains methods to interact with the database.

package fetch_data;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import entities.Product;

public class ProductModel {

	private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

	public Product find(int id) {
		Product product = null;
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			org.hibernate.query.Query query = session.createQuery("from Product where id = :id");
			query.setParameter("id", id);
			product = (Product) query.uniqueResult();
			transaction.commit();
		} catch (Exception e) {
			product = null;
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			session.close();
		}
		return product;
	}

}
package fetch_data;

import entities.Category;
import entities.Product;

public class Main {

	public static void main(String[] args) {

		ProductModel productModel = new ProductModel();
		CategoryModel categoryModel = new CategoryModel();

		System.out.println("********* Product Info with id is 1 *********");
		Product product = productModel.find(1);
		System.out.println("Id: " + product.getId());
		System.out.println("Name: " + product.getName());
		System.out.println("Price: " + product.getPrice());
		System.out.println("List of categories of this product");
		for(Category category : product.getCategories()) {
			System.out.println("\tCategory Id: " + category.getId());
			System.out.println("\tCategory Name: " + category.getName());
			System.out.println("\t---------------------------");
		}

		System.out.println("********* Category Info with id is 2 *********");
		Category category = categoryModel.find(2);
		System.out.println("Id: " + category.getId());
		System.out.println("Name: " + category.getName());
		System.out.println("List of products of this category");
		for(Product p : category.getProducts()) {
			System.out.println("\tProduct Id: " + p.getId());
			System.out.println("\tProduct Name: " + p.getName());
			System.out.println("\tPice: " + p.getPrice());
			System.out.println("\t---------------------------");
		}

	}

}




********* Product Info with id is 1 *********
Id: 1
Name: Laptop 2
Price: 1000.00
List of categories of this product
	Category Id: 1
	Category Name: Category 1
	---------------------------
	Category Id: 2
	Category Name: Category 2
	---------------------------
	Category Id: 3
	Category Name: Category 3
	---------------------------

********* Category Info with id is 2 *********
Id: 2
Name: Category 2
List of products of this category
	Product Id: 4
	Product Name: Computer 1
	Pice: 560.00
	---------------------------
	Product Id: 1
	Product Name: Laptop 2
	Pice: 1000.00
	---------------------------