Month: February 2016

Many to Many Bidirectional Relationship in Hibernate 4.X with Example

Posted on Updated on

Hibernate

 

Many-to-Many association is refer to @ManyToMany annotation in Hibernate 4.x, In this section we will discuss the relationship between User and Group, each User belongs to multiple Group’s similarly each Group belongs to multiple User’s, such relationship is called many-to-many association. In this relationship an intermediate table will be created that hold the reference of both tables. As you can see at below picture a “user_groups” table is created that is holding a reference of both tables i.e user_id act as a foreign key that refers to User Table and group_id acts also as a foreign key that refers to Groups Tables.

many-to-many

Pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itexperts</groupId>
<artifactId>HibernateTest</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>HibernateTest</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.0.1.Final</version>
</dependency>

<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.1.Final</version>
<classifier>tests</classifier>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>

</dependencies>
</project>

hibernate.cfg.xml : In given hibernate configuration file, we set “hbm2ddl.auto" is "Create" means every execution of Program, all scheme will be drop and recreated again.


<?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.url">jdbc:mysql://localhost:3306/mydb</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="show_sql">true</property>

<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="current_session_context_class">thread</property>

<mapping class="com.itexperts.hibernate.model.User" />
<mapping class="com.itexperts.hibernate.model.Group" />

</session-factory>
</hibernate-configuration>

User.java


package com.itexperts.hibernate.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "users")
public class User {

	@Id
	@GeneratedValue
	private long id;

	@Column(name = "USER_NAME")
	private String username;
	@Column(name = "EMAIL")
	private String email;
	@Column(name = "PHONE")
	private String phone;

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "user_groups", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "group_id"))
	private Set userGroups = new HashSet();

	public User() {
	}

	public User(String username, String email, String phone) {
		super();
		this.username = username;
		this.email = email;
		this.phone = phone;
	}

	public long getId() {
		return id;
	}

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

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public Set getUserGroups() {
		return userGroups;
	}

	public void setUserGroups(Set userGroups) {
		this.userGroups = userGroups;
	}

}


Group.java


package com.example.hibernate.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "GROUPS")
public class Group {

	@Id
	@GeneratedValue
	@Column(name = "GROUP_ID")
	private long id;

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

	@ManyToMany(cascade = { CascadeType.ALL},fetch=FetchType.LAZY)
	@JoinTable(name = "USERS_GROUPS", joinColumns = { @JoinColumn(name = "GROUP_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_ID") })
	private Set users = new HashSet();

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

	public long getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public Set getUsers() {
		return users;
	}

	public void setUsers(Set users) {
		this.users = users;
	}

	public void addUser(User user) {
		this.users.add(user);
	}

}


Main Class:-


package com.itexperts.relationship.example;

import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import com.itexperts.hibernate.model.Group;
import com.itexperts.hibernate.model.User;
import com.itexperts.utils.HibernateUtils;

public class MTMRelationalTest {

	public static void main(String args[]) {

		Group group1 = new Group("IT", "Admin");
		Group group2 = new Group("Transport", "Admin");
		Group group3 = new Group("Transport", "Super");
		Group group4 = new Group("Transport", "User");
		Group group5 = new Group("IT", "User");

		User user1 = new User("user1", "user1@gmail.com", "123-234324-234");
		user1.getUserGroups().add(group5);
		user1.getUserGroups().add(group1);
		user1.getUserGroups().add(group2);
		user1.getUserGroups().add(group4);

		User user2 = new User("user2", "user2@gmail.com", "123-234324-234");
		user2.getUserGroups().add(group5);
		user2.getUserGroups().add(group1);

		User user3 = new User("user3", "user3@gmail.com", "123-234324-234");
		user3.getUserGroups().add(group5);
		user3.getUserGroups().add(group1);
		user3.getUserGroups().add(group3);
		user3.getUserGroups().add(group4);

		User user4 = new User("user4", "user4@gmail.com", "123-234324-234");
		user4.getUserGroups().add(group3);
		user4.getUserGroups().add(group2);
		user4.getUserGroups().add(group4);

		User user5 = new User("user5", "user5@gmail.com", "123-234324-234");
		user5.getUserGroups().add(group5);
		user5.getUserGroups().add(group1);

		User user6 = new User("user6", "user6@gmail.com", "123-234324-234");
		user6.getUserGroups().add(group1);
		user6.getUserGroups().add(group4);

		Session session = HibernateUtils.getInstance().openSession();
		Transaction tx = session.beginTransaction();

	    session.save(user6);
		session.save(user5);
		session.save(user4);
		session.save(user3);
		session.save(user2);
		session.save(user1);

		
		tx.commit();
		session.close();
	}
}

Now fetch User & Group record by user Criteria API

MySQL native Joined Query to fetch User & Group records together:

SELECT users.id,users.user_name,users.phone,users.email,g.name,g.role
FROM users JOIN user_groups ug ON users.id = ug.user_id JOIN groups g
ON ug.group_id = g.id WHERE users.id=1

Using Criteria Query fetch and generate same SQL query as below:-


		java.util.List listOfUser = (java.util.List) session
				.createCriteria(User.class, "user")
				.createAlias("user.userGroups", "g")
				.setFetchMode("user.userGroups", FetchMode.JOIN)
				.add(Restrictions.eq("user.id", 1L)).list();

Hibernate Generate following SQL Code here:-


Hibernate: 
    select
        this_.id as id0_1_,
        this_.EMAIL as EMAIL0_1_,
        this_.PHONE as PHONE0_1_,
        this_.USER_NAME as USER4_0_1_,
        usergroups3_.user_id as user1_0_,
        g1_.id as group2_,
        g1_.id as id1_0_,
        g1_.CREATED_DATE as CREATED2_1_0_,
        g1_.NAME as NAME1_0_,
        g1_.ROLE as ROLE1_0_ 
    from
        users this_ 
    inner join
        user_groups usergroups3_ 
            on this_.id=usergroups3_.user_id 
    inner join
        groups g1_ 
            on usergroups3_.group_id=g1_.id 
    where
        this_.id=?


 

MongoDB with Hibernate ORM

Posted on Updated on

Hibernate OGM

Welcome to next interesting topics “NoSQL with Hibernate” ,basically Hibernate OGM ( Object graph mapping) provides JPA ( Java persistent )  for supports NoSQL solution.

Wide range of backends

OGM talks to NoSQL backends via store-specific dialects. Currently there is support for

  • Key/Value: Infinispan; Ehcache; Redis (tech preview)
  • Document: MongoDB; CouchDB (tech preview)
  • Graph: Neo4j
  • Wide-column: Cassandra (tech preview)

Rich query capabilities

Hibernate OGM supports several ways for searching entities and returning them as Hibernate managed objects:

  • JP-QL queries (we convert them into a native backend query)
  • datastore specific native queries
  • full-text queries, using Hibernate Search as indexing engine

And more…​

  • When JPA isn’t enough, Hibernate OGM extends it with family-specific and product-specific options. That way, the power of the backend is at your fingertips. All that in a type-safe way.
  • Mixing several NoSql datastores in one application, e.g. use Neo4j for your friendship graph and MongoDB for your blog posts. Or mix NoSQL and relational databases.
  • Support for implicit data migrations upon data load (later)
  • Denormalize data declaratively for faster retrieval (later)

One of most rich feature Hibernate Framework Provides us to integrate with any relational Database which enabled to plugins with most of RDMS Database. In this part, we will build a sample application program through we can integrate with mongoDB ( NoSQL ) using Hibernate OGM Framework. But prior to this,  you must have knowledge of Hibernate/JPA as well as mongoDB.

In this example, we have made a relationship between UserProfile and composite element UserSkills, so every UserProfile has some skills set. see at end snapshots attachment that stored UserProfile’s Document in MongoDB.

JTA transaction is not enabled in this part, we will cover in next part.

 

Tools Configuration:-

  1. JDK 1.7 or higher
  2. Maven 3.X
  3. MongoDB

Project hierarchy in Eclipse :-

hibernate-nosql-project-hierar

 

 

 

 

 

 

 

 

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>HibernateNoSQL</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>HibernateNoSQL</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mongodb.driver.version>2.7.2</mongodb.driver.version>
<hibernateOgmVersion>4.2.0.Final</hibernateOgmVersion>
</properties>
<dependencies>

<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-mongodb</artifactId>
<version>${hibernateOgmVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-core</artifactId>
<version>${hibernateOgmVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate.ogm</groupId>
<artifactId>hibernate-ogm-infinispan</artifactId>
<version>${hibernateOgmVersion}</version>
</dependency>

<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>${mongodb.driver.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>

<dependency>
<groupId>jboss</groupId>
<artifactId>jbossjta</artifactId>
<version>4.2.2.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
<version>1.0.1.Final</version>
</dependency>
</dependencies>
</project>

HibernateMongoSessionUtils.Java : 


package com.example.app.utils;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.ogm.cfg.OgmConfiguration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateMongoSessionUtils {
	private static SessionFactory SESSION_FACTORY;
	private static ServiceRegistry SERVICE_REGISTRY;

	private HibernateMongoSessionUtils() {
	}

	public static SessionFactory getInstance() {

		if (SESSION_FACTORY == null) {
			synchronized (SessionFactory.class) {
				if (SESSION_FACTORY == null) {
					Configuration config = new OgmConfiguration().configure("hibernate.cfg.xml");
					SERVICE_REGISTRY = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
					SESSION_FACTORY = config.buildSessionFactory(SERVICE_REGISTRY);
				}
			}
		}
		return SESSION_FACTORY;

	}
}


UserProfile.Java : Entity class that contained list of embedded UserSkills.


package com.example.hibernate.model;

import java.util.Date;
import java.util.List;

import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.search.annotations.IndexedEmbedded;

@Entity
public class UserProfile {

	@Id
	@GeneratedValue(generator = "uuid")
	@GenericGenerator(name = "uuid", strategy = "uuid2")
	private String id;

	private String name;
	private String email;
	private String phone;
	private String gender;
	private String dateOfBirth;

	private String summary;

	private Date created_date;
	private Date last_modified;

	@ElementCollection
	@IndexedEmbedded
	private List skills;

	public UserProfile() {
	}

	public String getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(String dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public Date getCreated_date() {
		return created_date;
	}

	public void setCreated_date(Date created_date) {
		this.created_date = created_date;
	}

	public Date getLast_modified() {
		return last_modified;
	}

	public void setLast_modified(Date last_modified) {
		this.last_modified = last_modified;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("UserProfile [id=").append(id).append(", name=")
				.append(name).append(", email=").append(email)
				.append(", phone=").append(phone).append(", gender=")
				.append(gender).append(", dateOfBirth=").append(dateOfBirth)
				.append(", summary=").append(summary).append(", created_date=")
				.append(created_date).append(", last_modified=")
				.append(last_modified).append(", skills=").append(skills)
				.append("]");
		return builder.toString();
	}

	public List getSkills() {
		return skills;
	}

	public void setSkills(List skills) {
		this.skills = skills;
	}
}


UserSkills.Java : Embedded model class.


package com.example.hibernate.model;

import javax.persistence.Embeddable;

@Embeddable
public class UserSkills {
	private String name;

	public UserSkills() {
	}

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

	public String getName() {
		return name;
	}

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

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("UserSkills [name=").append(name).append("]");
		return builder.toString();
	}

}


Main Class


package com.example.main;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.example.app.utils.HibernateMongoSessionUtils;
import com.example.hibernate.model.UserProfile;
import com.example.hibernate.model.UserSkills;
/**
 * 
 * 
 * @author Ajay Kumar
 *
 */
public class MongoDBTest1 {
	
	public static void main(String args[]){
		
		Session session = HibernateMongoSessionUtils.getInstance().openSession();
		Transaction tx = session.beginTransaction();
		
		UserProfile userProfile = new UserProfile();
		
		userProfile.setName("Ajay Kumar Gupta");
		userProfile.setPhone("1234567890");
		userProfile.setEmail("ajay@domain.com");
		userProfile.setSummary("This is my Objective");
		userProfile.setGender("Male");
		userProfile.setDateOfBirth("02-Aug-1986");
		userProfile.setCreated_date(new Date());
		userProfile.setLast_modified(new Date());
		
		UserSkills skill1 = new UserSkills("Java,J2EE");
		UserSkills skill2 = new UserSkills("Spring");
		UserSkills skill3 = new UserSkills("Angular");
		UserSkills skill4 = new UserSkills("Big Database");
		UserSkills skill5 = new UserSkills("Hibernate");
		UserSkills skill6 = new UserSkills("C/C++");
		UserSkills skill7 = new UserSkills("Oracle");
		
		List userSkills = new ArrayList();
		userSkills.add(skill7);
		userSkills.add(skill6);
		userSkills.add(skill5);
		userSkills.add(skill4);
		userSkills.add(skill3);
		userSkills.add(skill2);
		userSkills.add(skill1);

		userProfile.setSkills(userSkills);
		
		// Save a Document into MongoDB
		session.save(userProfile);
		
		// fetch a Document from MongoDB
		System.out.println(userProfile.getId());
		UserProfile get_useProfile =  (UserProfile)session.get(UserProfile.class,userProfile.getId());
		System.out.println(" Fetch UserProfile Information :"+get_useProfile);
		
		tx.commit();
		session.close();
	}

}


hibernate.cfg.xml


<?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.ogm.datastore.provider">mongodb</property>
 <property name="hibernate.ogm.datastore.database">myMongoDB</property>
 <property name="hibernate.ogm.datastore.host">127.0.0.1</property>
 <property name="hibernate.ogm.datastore.port">27017</property>
 <property name="hibernate.ogm.datastore.create_database">true</property>
 <property name="hibernate.ogm.mongodb.connection_timeout">1000</property>

 <mapping class="com.example.hibernate.model.UserProfile" />
 </session-factory>
</hibernate-configuration>

Stored Document in MongoDB:-

hibernate-mongodb-output

 

Thanks
Ajay kumar
———-

Hibernate Table Per Concrete class using Annotation

Posted on Updated on

Hibernate

This Hibernate inheritance strategy as  name implies that Table Per Concrete class mean One table for each concrete class. Each table has inherited all properties of the class as well as inherited properties from root class.

In this strategy, Each concrete class gets a duplicate copy of parent class properties, also the Data store in Concrete class Tables are not normalized.

In below snippet code example, session.get() is called that pulled out a record identify i.e 1L and printed “Bill_Amt” value on the console. If you see Hibernate generated SQL on the Console,  Hibernate generates SQL UNION when performing fetching a record.


   session = HibernateUtils.getInstance().openSession();
   trx = session.beginTransaction();

   BillAccountDetails billAccountDetails1 = (BillAccountDetails)session.get(BillAccountDetails.class,1L);
   System.out.println(billAccountDetails1.getBill_amt());

   trx.commit();
   session.close();

Hibernate generate following SQL command :-


Hibernate: 
    select
        billaccoun0_.billAccount_id as billAcco1_0_0_,
        billaccoun0_.Bill_Amt as Bill2_0_0_,
        billaccoun0_.createdDate as createdD3_0_0_,
        billaccoun0_.account as account1_0_,
        billaccoun0_.Bank_Name as Bank2_1_0_,
        billaccoun0_.exp_Month as exp1_2_0_,
        billaccoun0_.exp_Year as exp2_2_0_,
        billaccoun0_.Card_Number as Card3_2_0_,
        billaccoun0_.clazz_ as clazz_0_ 
    from
        ( select
            billAccount_id,
            Bill_Amt,
            createdDate,
            account,
            Bank_Name,
            null as exp_Month,
            null as exp_Year,
            null as Card_Number,
            1 as clazz_ 
        from
            BankAccount 
        union
        select
            billAccount_id,
            Bill_Amt,
            createdDate,
            null as account,
            null as Bank_Name,
            exp_Month,
            exp_Year,
            Card_Number,
            2 as clazz_ 
        from
            CreditCardAccount 
    ) billaccoun0_ 
where
    billaccoun0_.billAccount_id=?
 

@Inheritance :- It’s defined which inheritance strategy to be used for Entity class hierarchy. If the Inheritanceannotation is not specified or if no inheritance type is specified for an entity class hierarchy, theSINGLE_TABLE mapping strategy is used.

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

 

As earlier, we supposed we have an abstract BillAccountDetails class with their implementor are CreditCardAccountand BankAccount respectively.

 

BillAccountDetails.java


package com.itexperts.hibernate.model;

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.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="BillAccountDetails")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BillAccountDetails {

	@Id
	@Column(name="billAccount_id")
	@GeneratedValue(strategy = GenerationType.TABLE)
	private long id;

	@Temporal(TemporalType.DATE)
	private Date createdDate;

	@Column(name = "Bill_Amt")
	private long bill_amt;

	public long getBill_amt() {
		return bill_amt;
	}

	public void setBill_amt(long bill_amt) {
		this.bill_amt = bill_amt;
	}

	public long getId() {
		return id;
	}

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

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}
}

 

BankAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
@AttributeOverrides({
			@AttributeOverride(name="id",column=@Column(name="billAccount_id")),
			@AttributeOverride(name="name",column=@Column(name="billAccount_name"))
})
public class BankAccount extends BillAccountDetails{
	
	@Column(name="account")
	private String account;
	
	@Column(name="Bank_Name")
	private String bankname;

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getBankname() {
		return bankname;
	}

	public void setBankname(String bankname) {
		this.bankname = bankname;
	}
}


CreditCardAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
@AttributeOverrides({
			@AttributeOverride(name="id",column=@Column(name="billAccount_id")),
			@AttributeOverride(name="name",column=@Column(name="billAccount_name"))
})
public class CreditCardAccount extends BillAccountDetails {

	@Column(name = "Card_Number")
	private String number;

	@Column(name = "exp_Month")
	private String expiry_month;

	@Column(name = "exp_Year")
	private String expiry_year;

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public String getExpiry_month() {
		return expiry_month;
	}

	public void setExpiry_month(String expiry_month) {
		this.expiry_month = expiry_month;
	}

	public String getExpiry_year() {
		return expiry_year;
	}

	public void setExpiry_year(String expiry_year) {
		this.expiry_year = expiry_year;
	}
}

hibernate.cfg.xml


<?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.url">jdbc:mysql://localhost:3306/mydb</property>
 <property name="connection.username">root</property>
 <property name="connection.password">root</property>
 <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
 <property name="show_sql">true</property>
 
 <!-- <property name="format_sql">true</property> -->
 <property name="hbm2ddl.auto">create</property>
 
 <!-- JDBC connection pool (use the built-in) -->
 <property name="connection.pool_size">1</property>
 <property name="current_session_context_class">thread</property>
 
 <mapping class="com.itexperts.hibernate.model.BillAccountDetails"/> 
 <mapping class="com.itexperts.hibernate.model.BankAccount"/> 
 <mapping class="com.itexperts.hibernate.model.CreditCardAccount"/> 
  
</session-factory>
</hibernate-configuration>

Main Class :-


package com.itexperts.relationship.example;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.itexperts.hibernate.model.BankAccount;
import com.itexperts.hibernate.model.CreditCardAccount;
import com.itexperts.utils.HibernateUtils;

public class TablePerSubClassHierarchyHibernateTest {
	
	public static void main(String args[]){
		
		BankAccount bankAccount1 = new BankAccount();
		bankAccount1.setCreatedDate(new Date());
		bankAccount1.setAccount("A234234234");
		bankAccount1.setBankname("ICICI Bank");
		bankAccount1.setBill_amt(220);
		
		CreditCardAccount cardAccount1 = new CreditCardAccount();
		cardAccount1.setCreatedDate(new Date());
		cardAccount1.setExpiry_month("Aug");
		cardAccount1.setExpiry_year("2017");
		cardAccount1.setBill_amt(660);
		cardAccount1.setNumber("2324-23423-23423-234-234324");
		
		Session session = HibernateUtils.getInstance().openSession();
		Transaction trx = session.beginTransaction();
		
		session.save(bankAccount1);
		session.save(cardAccount1);
		
		trx.commit();
		session.close();	
	}
}

Generated Code here:-

hibernate-per-concret-console.

Mysql Tables – Only Two tables get created here, each table hold complete information of own as well Inherited. 

 

 


Example Section here:

 

thanks

Hibernate Table Per Subclass using Annotation

Posted on Updated on

Hibernate

Table Per Subclass using Annotation:-

In the case of Table sub-class strategy, Each sub-class can also be own table. This is called the table-per-subclass mapping strategy. An inherited state is retrieved by joining with the table of the superclass. A discriminator column is not required for this mapping strategy. Each subclass must, however, declare a table column holding the object identifier. The primary key of this table is also a foreign key to the superclass table and described by the @PrimaryKeyJoinColumns or the <key> element.

@Inheritance :-  It’s defined which inheritance strategy to be used for Entity class hirarchy. If the Inheritance annotation is not specified or if no inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.

Inheritance strategy:

@Inheritance(strategy = InheritanceType.JOINED)

@PrimaryKeyJoinColumns :- Specify a Key element (“Column”) name of root class which reference works in sub-class as a foreign key.

@PrimaryKeyJoinColumn(name=”id”)

 

As earlier, we supposed we have an abstract BillAccountDetails class with their implementor are CreditCardAccountand BankAccount respectively.

 

BillAccountDetails.java


package com.itexperts.hibernate.model;

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.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "BankDetails")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BillAccountDetails {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	@Temporal(TemporalType.DATE)
	private Date createdDate;

	@Column(name = "Bill_Amt")
	private long bill_amt;

	public long getBill_amt() {
		return bill_amt;
	}

	public void setBill_amt(long bill_amt) {
		this.bill_amt = bill_amt;
	}

	public long getId() {
		return id;
	}

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

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}

}

 

BankAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;

@Entity
@PrimaryKeyJoinColumn(name="id")
public class BankAccount extends BillAccountDetails{
	
	@Column(name="account")
	private String account;
	
	@Column(name="Bank_Name")
	private String bankname;

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getBankname() {
		return bankname;
	}

	public void setBankname(String bankname) {
		this.bankname = bankname;
	}
}

CreditCardAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;

@Entity
@PrimaryKeyJoinColumn(name="id")
public class CreditCardAccount extends BillAccountDetails {

	@Column(name = "Card_Number")
	private String number;

	@Column(name = "exp_Month")
	private String expiry_month;

	@Column(name = "exp_Year")
	private String expiry_year;

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public String getExpiry_month() {
		return expiry_month;
	}

	public void setExpiry_month(String expiry_month) {
		this.expiry_month = expiry_month;
	}

	public String getExpiry_year() {
		return expiry_year;
	}

	public void setExpiry_year(String expiry_year) {
		this.expiry_year = expiry_year;
	}
}

hibernate.cfg.xml


<?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.url">jdbc:mysql://localhost:3306/mydb</property>
 <property name="connection.username">root</property>
 <property name="connection.password">root</property>
 <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
 <property name="show_sql">true</property>
 
 <!-- <property name="format_sql">true</property> -->
 <property name="hbm2ddl.auto">create</property>
 
 <!-- JDBC connection pool (use the built-in) -->
 <property name="connection.pool_size">1</property>
 <property name="current_session_context_class">thread</property>
 
 <mapping class="com.itexperts.hibernate.model.BillAccountDetails"/> 
 <mapping class="com.itexperts.hibernate.model.BankAccount"/> 
 <mapping class="com.itexperts.hibernate.model.CreditCardAccount"/> 
  
</session-factory>
</hibernate-configuration>

Main Class :-


package com.itexperts.relationship.example;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.itexperts.hibernate.model.BankAccount;
import com.itexperts.hibernate.model.CreditCardAccount;
import com.itexperts.utils.HibernateUtils;

public class TablePerSubClassHierarchyHibernateTest {
	
	public static void main(String args[]){
		
		BankAccount bankAccount1 = new BankAccount();
		bankAccount1.setCreatedDate(new Date());
		bankAccount1.setAccount("A234234234");
		bankAccount1.setBankname("ICICI Bank");
		bankAccount1.setBill_amt(220);
		
		CreditCardAccount cardAccount1 = new CreditCardAccount();
		cardAccount1.setCreatedDate(new Date());
		cardAccount1.setExpiry_month("Aug");
		cardAccount1.setExpiry_year("2017");
		cardAccount1.setBill_amt(660);
		cardAccount1.setNumber("2324-23423-23423-234-234324");
		
		Session session = HibernateUtils.getInstance().openSession();
		Transaction trx = session.beginTransaction();
		
		session.save(bankAccount1);
		session.save(cardAccount1);
		
		trx.commit();
		session.close();	
	}
}

Generated Output:-

Hibernate: alter table BankAccount drop foreign key FK305B8831719F6CB5
Hibernate: alter table CreditCardAccount drop foreign key FKCD03EC24719F6CB5
Hibernate: drop table if exists BankAccount
Hibernate: drop table if exists BankDetails
Hibernate: drop table if exists CreditCardAccount
Hibernate: create table BankAccount (account varchar(255), Bank_Name varchar(255), id bigint not null, primary key (id))
Hibernate: create table BankDetails (id bigint not null auto_increment, Bill_Amt bigint, createdDate date, primary key (id))
Hibernate: create table CreditCardAccount (exp_Month varchar(255), exp_Year varchar(255), Card_Number varchar(255), id bigint not null, primary key (id))
Hibernate: alter table BankAccount add index FK305B8831719F6CB5 (id), add constraint FK305B8831719F6CB5 foreign key (id) references BankDetails (id)
Hibernate: alter table CreditCardAccount add index FKCD03EC24719F6CB5 (id), add constraint FKCD03EC24719F6CB5 foreign key (id) references BankDetails (id)
Hibernate: insert into BankDetails (Bill_Amt, createdDate) values (?, ?)
Hibernate: insert into BankAccount (account, Bank_Name, id) values (?, ?, ?)
Hibernate: insert into BankDetails (Bill_Amt, createdDate) values (?, ?)
Hibernate: insert into CreditCardAccount (exp_Month, exp_Year, Card_Number, id) values (?, ?, ?, ?)

Mysql Tables –

TablePerSubClassHierarchyHibernateTest-snapshot


Example Section here:

Hibernate Inheritance strategy

Posted on Updated on

Hibernate

 

 

 

Java is a language supporting polymorphism: a class can inherit from another. It is possible to use different mapping strategies for different branches of the same inheritance hierarchy. You can then make use of implicit polymorphism to achieve polymorphism across the whole hierarchy

Hibernate supports three type of Inheritance mapping strategy:

  1. Table Per Hierarchy : A single table will be created to store properties of sub-class hierarchy. 
  2. Table Per Concrete class :- one table per class and subclass is present and each table persist the properties specific to a given subclass. The state of the entity is then stored in its corresponding class table and all its superclasses
  3. Table Per Subclass :- one table per concrete class and subclass is present and each table persist the properties of the class and its superclasses. The state of the entity is then stored entirely in the dedicated table for its class.

Example Section here:

  1. Table Per Hierarchy using Annotation
  2. Table per Concrete using Annotation
  3. Table Per Subclass using Annotation

Hibernate Table Per Hierarchy using Annotation

Posted on Updated on

Hibernate

 

 

 

See the previous Page for Hibernate with inheritance mapping.

In this Page we will see Table per hierarchy using Annotation, In this approach, only one table will be created that store all properties of sub-classes hierarchy. A single table hosts all the instance of class hierarchy.

Each sub-classes declare it own persistent properties. Version and identifier ( ID as primary key ) are assume to be inherited from super class. Each sub-class in hierarchy must define a unique Discriminator using @DiscriminatorValue. If this is not specified, the fully qualified Java class name is used.

Let see the example of Tabe per hierarchy below:-

@Inheritance :-  It’s defined which inheritance strategy to be used for Entity class hirarchy. If the Inheritance annotation is not specified or if no inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.

Inheritance strategy:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

@DiscriminatorValue: Each class of the hierarchy to specify the value stored in the discriminator column for a given entity. If you do not set @DiscriminatorValue on a class, the fully qualified class name is used.

@DiscriminatorColumn(name = "Bank", discriminatorType = DiscriminatorType.STRING)

@DiscriminatorColumn: It’s defined a discriminator column which is used to add extra column i.e discriminator column as well as discriminator type.

@DiscriminatorColumn(name = "BILLING_DETAIL_TYPE", discriminatorType = DiscriminatorType.STRING)

Here, we suppose we have an abstract BillAccountDetails class with their implementor are CreditCardAccount and BankAccount respectively.

 

BillAccountDetails.java


package com.itexperts.hibernate.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "BankDetails")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "BILLING_DETAIL_TYPE", discriminatorType = DiscriminatorType.STRING)

public abstract class BillAccountDetails {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;

	@Temporal(TemporalType.DATE)
	private Date createdDate;

	@Column(name = "Bill_Amt")
	private long bill_amt;

	public long getBill_amt() {
		return bill_amt;
	}

	public void setBill_amt(long bill_amt) {
		this.bill_amt = bill_amt;
	}

	public long getId() {
		return id;
	}

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

	public Date getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Date createdDate) {
		this.createdDate = createdDate;
	}
}

 

BankAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("Bank")
public class BankAccount extends BillAccountDetails{
	
	@Column(name="account")
	private String account;
	
	@Column(name="Bank_Name")
	private String bankname;

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getBankname() {
		return bankname;
	}

	public void setBankname(String bankname) {
		this.bankname = bankname;
	}
}

CreditCardAccount.Java


package com.itexperts.hibernate.model;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("Credit")
public class CreditCardAccount extends BillAccountDetails {

	@Column(name = "Card_Number")
	private String number;

	@Column(name = "exp_Month")
	private String expiry_month;

	@Column(name = "exp_Year")
	private String expiry_year;

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public String getExpiry_month() {
		return expiry_month;
	}

	public void setExpiry_month(String expiry_month) {
		this.expiry_month = expiry_month;
	}

	public String getExpiry_year() {
		return expiry_year;
	}

	public void setExpiry_year(String expiry_year) {
		this.expiry_year = expiry_year;
	}
}

hibernate.cfg.xml


<?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.url">jdbc:mysql://localhost:3306/mydb</property>
 <property name="connection.username">root</property>
 <property name="connection.password">root</property>
 <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
 <property name="show_sql">true</property>
 
 <!-- <property name="format_sql">true</property> -->
 <property name="hbm2ddl.auto">create</property>
 
 <!-- JDBC connection pool (use the built-in) -->
 <property name="connection.pool_size">1</property>
 <property name="current_session_context_class">thread</property>
 
 <mapping class="com.itexperts.hibernate.model.BillAccountDetails"/> 
 <mapping class="com.itexperts.hibernate.model.BankAccount"/> 
 <mapping class="com.itexperts.hibernate.model.CreditCardAccount"/> 
  
</session-factory>
</hibernate-configuration>

Main Class :-

package com.itexperts.relationship.example;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.itexperts.hibernate.model.BankAccount;
import com.itexperts.hibernate.model.CreditCardAccount;
import com.itexperts.utils.HibernateUtils;

public class TablePerClassHierarchyHibernateTest {
	
	public static void main(String args[]){
		
		BankAccount bankAccount1 = new BankAccount();
		bankAccount1.setCreatedDate(new Date());
		bankAccount1.setAccount("A234234234");
		bankAccount1.setBankname("ICICI Bank");
		bankAccount1.setBill_amt(220);
		
		CreditCardAccount cardAccount1 = new CreditCardAccount();
		cardAccount1.setCreatedDate(new Date());
		cardAccount1.setExpiry_month("Aug");
		cardAccount1.setExpiry_year("2017");
		cardAccount1.setBill_amt(660);
		cardAccount1.setNumber("2324-23423-23423-234-234324");
		
		Session session = HibernateUtils.getInstance().openSession();
		Transaction trx = session.beginTransaction();
		
		session.save(bankAccount1);
		session.save(cardAccount1);
		
		trx.commit();
		session.close();	
	}
}

 

Generated Output:-

Hibernate: drop table if exists BankDetails
Hibernate: create table BankDetails (BILLING_DETAIL_TYPE varchar(31) not null, id bigint not null auto_increment, Bill_Amt bigint, createdDate date, account varchar(255), Bank_Name varchar(255), exp_Month varchar(255), exp_Year varchar(255), Card_Number varchar(255), primary key (id))
Hibernate: insert into BankDetails (Bill_Amt, createdDate, account, Bank_Name, BILLING_DETAIL_TYPE) values (?, ?, ?, ?, 'Bank')
Hibernate: insert into BankDetails (Bill_Amt, createdDate, exp_Month, exp_Year, Card_Number, BILLING_DETAIL_TYPE) values (?, ?, ?, ?, ?, 'Credit')

Update table record:-

TablePerClassHierarchyHibernateTest-large


Example Section here:

Transient, Persistent and Detached Object in Hibernate

Posted on Updated on

Hibernate

Hibernate is an Object-relational mapping Framework for Java language. It’s provided a framework for mapping an object-oriented domain model to a  relational database.

 

Primary feature’s of Hibernate is mapping Java model object to a relational database, also  Hibernate provides JPA for NoSQL i.e MongoDB.

Hibernate Object States :-

hibernate-state

 

Transient Object:- A model is called Transient which is just created using new operator and it’s not associate to any Session object. Therefore any changes on Transient Object wouldn’t be reflected to database.

  • Object created using new operator that has not been save in the Database.
  • This Object doesn’t map to row in database.
  • This Object is not associate with Hibernate Session.
  • State of such Object is lost if no object is referencing them.

Persistent Object:- A model is called Persistent which is associated with Hibernate Session and represent an identifier in a Database. When we call save(), saveOrUpdate(),persist() and merge() methods of Session then transient object become to Persistent object subsequently any changes on Persistent object will reflected database row.

  • A persistent Object is associated with Session so any modification is cached first in Session.( By default first level Cache – Session )
  • Persistent Object is unique in per Session so if you try to fetch a database identity twice then only one Select Command will be fired and you will have the same object for two requests.
  • When you call get() and load() method to fetch the same Database identity twice then either zero or only one Select Command will be fired – again it depend on that identity exist in Session Cache once identity gets available in Session Cache then it wouldn’t be hit to Database.

Detached Object:- A model object is called Detached Object which was associated with a session previously but now it’s not due to some reason either Session has been closed or evict(),clear() and closed() methods has been called.

  • A detached object is associated with a Database identifier but it’s not associate with any Session.
  • Any changes on a Detached object is not synchronized with Database.
  • Detached Object can be re-attached by calling update(), saveOrUpdate() and merge() methods.
  • When a Session object is closed then All Persistent Object become Detached Object.

Below are some snippet code of Hibernate Object State:- 

Transient Object:-    A Transient Object is a Model/Pojo/Bean/Entity class which is instantiated by new operator just like create an Object in Java using new operator.


@Entity
@Table(name = "USERPROFILE")
public class UserProfile {

	@Id
	@GeneratedValue
	private long id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "EMAIL")
	private String email;

	@Column(name = "PHONE")
	private String phone;
        .....
        // getter and setter
 

 

UserProfile user1 = new UserProfile("user1", "use1@domain.com", "234234234", "This is about user1");
UserProfile user2 = new UserProfile("user2", "use2@domain.com", "666666656", "This is about user2");
UserProfile user3 = new UserProfile("user3", "use3@domain.com", "343466655", "This is about user3");

Here, UserProfile is an Entity class which is just created and it’s not associated with any session.

Persistent Object:- below snippet code, a transient objects transit to persistent state after calling session.save(..).


Session session = HibernateUtils.getInstance().openSession();
		Transaction tx = session.beginTransaction();

		session.save(user3);
		session.save(user2);
		session.save(user1);

		tx.commit();
		session.close();

 

Ditched Object:  below snippet code, UserProfile’s object user1,user2 and user3 has been persistent but in next line of code, session.evict(user3) has been called which means user3 object is disconnected with Session now it’s state is Detached while rest two objects state is still persistent. see example


                Session session = HibernateUtils.getInstance().openSession();
		Transaction tx = session.beginTransaction();

		session.save(user3);
		session.save(user2);
		session.save(user1);
                
                session.evict(user3);

		tx.commit();
		session.close();