+ All Categories
Home > Education > Hibernate inheritance and relational mappings with examples

Hibernate inheritance and relational mappings with examples

Date post: 11-Apr-2017
Category:
Upload: er-gaurav-kumar
View: 63 times
Download: 0 times
Share this document with a friend
39
Hibernate INHERITANCE AND RELATIONAL MAPPINGS - BY GAURAV KUMAR
Transcript
Page 1: Hibernate inheritance and relational mappings with examples

HibernateINHERITANCE AND RELATIONAL MAPPINGS

- BY GAURAV KUMAR

Page 2: Hibernate inheritance and relational mappings with examples

Inheritance

Java is an object oriented language. It is possible to implement Inheritance in Java. Inheritance is one of the most visible facets of Object-relational mismatch. Object oriented systems can model both “is a” and “has a” relationship. Relational model supports only “has a” relationship between two entities. Hibernate can help you map such Objects with relational tables. But you need to choose certain mapping strategy based on your needs.

Page 3: Hibernate inheritance and relational mappings with examples

One Table Per Class Hierarchy

Suppose we have a class Person with subclass Employee. The properties of each class are:• class Person - firstname - lastname • class Employee - joining_date - department_name In One Table per Class Hierarchy scheme, we store all the class hierarchy in a single SQL table. A discriminator is a key to uniquely identify the base type of the class hierarchy.Following are the advantages and disadvantages of One Table per Class Hierarchy scheme.AdvantageThis hierarchy offers the best performance even for in the deep hierarchy since single select may suffice.DisadvantageChanges to members of the hierarchy require column to be altered, added or removed from the table.

Page 4: Hibernate inheritance and relational mappings with examples

One Table Per Class HierarchyExample:-package com.chaetu.training;

import javax.persistence.*;

@Entity@Table(name = "PERSON")@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn( name="discriminator", discriminatorType=DiscriminatorType.STRING)@DiscriminatorValue(value="P")public class Person {

@Id@GeneratedValue@Column(name = "PERSON_ID")private Long personId;@Column(name = "FIRSTNAME")private String firstname;@Column(name = "LASTNAME")private String lastname;

// Constructors and Getter/Setter methods, }

Page 5: Hibernate inheritance and relational mappings with examples

One Table Per Class HierarchyThe Person class is the root of hierarchy. Hence we have used some annotations to make it as the root.

@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

@DiscriminatorColumn – Is used to define the discriminator column for the SINGLE_TABLE and JOINED inheritance mapping strategies. The strategy and the discriminator column are only specified in the root of an entity class hierarchy or sub hierarchy in which a different inheritance strategy is applied

If the @DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to "DTYPE" and the discriminator type to DiscriminatorType.STRING.

@DiscriminatorValue – Is used to specify the value of the discriminator column for entities of the given type. The DiscriminatorValue annotation can only be specified on a concrete entity class. If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy

Page 6: Hibernate inheritance and relational mappings with examples

One Table Per Class HierarchyExample-

package com.chetu.training;import java.util.Date;import javax.persistence.*;

@Entity@Table(name="PERSON")@DiscriminatorValue("E")public class Employee extends Person {

@Column(name="joining_date")private Date joiningDate;

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

// Constructors and Getter/Setter methods, }

Page 7: Hibernate inheritance and relational mappings with examples

One Table Per Class Hierarchy

Example:package com.chetu.training;

import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;public class Main {

public static void main(String[] args) {SessionFactory sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();session.beginTransaction();

Person person = new Person("Steve", "Balmer");session.save(person);Employee employee = new Employee("James", "Gosling", "Marketing", new Date());session.save(employee);

session.getTransaction().commit();session.close();

}}

Page 8: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassSuppose we have a class Person with subclasses Employee and Owner. Following the class diagram and relationship of these classes.

In One Table per Concrete class scheme, each concrete class is mapped as normal persistent class. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. In this scheme, the mapping of the subclass repeats the properties of the parent class.

Following are the advantages and disadvantages of One Table per Subclass scheme.

AdvantagesThis is the easiest method of Inheritance mapping to implement.

DisadvantagesData thats belongs to a parent class is scattered across a number of subclass tables, which represents concrete classes.This hierarchy is not recommended for most cases.Changes to a parent class is reflected to large number of tables.

Page 9: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassExample: Package com.chetu.training;

import javax.persistence.*;

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

@Id@Column(name = "PERSON_ID")private Long personId;

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

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

public Person() {

}public Person(String firstname, String lastname) {

this.firstname = firstname;this.lastname = lastname;

}// Getter and Setter methods,

}

Page 10: Hibernate inheritance and relational mappings with examples

One Table Per Concrete Class

@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

@InheritanceType – Defines inheritance strategy options. TABLE_PER_CLASS is a strategy to map table per concrete class.

Page 11: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassExample:package com.chetu.training;

import java.util.Date;import javax.persistence.*;@Entity@Table(name="EMPLOYEE")@AttributeOverrides({ @AttributeOverride(name="firstname", column=@Column(name="FIRSTNAME")), @AttributeOverride(name="lastname", column=@Column(name="LASTNAME"))})public class Employee extends Person {

@Column(name="joining_date")private Date joiningDate;

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

public Employee() {}public Employee(String firstname, String lastname, String departmentName, Date joiningDate) {

super(firstname, lastname);this.departmentName = departmentName;this.joiningDate = joiningDate;

}// Getter and Setter methods,

}

Page 12: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassExample:package com.chetu.training;import javax.persistence.*;

@Entity@Table(name="OWNER")@AttributeOverrides({ @AttributeOverride(name="firstname", column=@Column(name="FIRSTNAME")), @AttributeOverride(name="lastname", column=@Column(name="LASTNAME"))})public class Owner extends Person {

@Column(name="stocks")private Long stocks;

@Column(name="partnership_stake")private Long partnershipStake;

public Owner() {}public Owner(String firstname, String lastname, Long stocks, Long partnershipStake) {

super(firstname, lastname);this.stocks = stocks;this.partnershipStake = partnershipStake;

}// Getter and Setter methods,

}

Page 13: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassBoth Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used @AttributeOverrides to map them.

@AttributeOverrides – This annotation is used to override mappings of multiple properties or fields.

@AttributeOverride – The AttributeOverride annotation is used to override the mapping of a Basic (whether explicit or default) property or field or Id property or field.

The AttributeOverride annotation may be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping defined by the mapped superclass or embeddable class. If the AttributeOverride annotation is not specified, the column is mapped the same as in the original mapping.

Thus in over case, firstname and lastname are defined in parent class Person and mapped in child class Employee and Owner using @AttributeOverrides annotation.

This strategy supports one-to-many associations provided that they are bidirectional. This strategy does not support the IDENTITY generator strategy: the id has to be shared across several tables. Consequently, when using this strategy, you should not use AUTO nor IDENTITY. Note that in below Main class we specified the primary key explicitly.

Page 14: Hibernate inheritance and relational mappings with examples

One Table Per Concrete ClassExample: package com.chetu.training;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;public class Main {

public static void main(String[] args) {SessionFactory sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();session.beginTransaction();

Person person = new Person("Steve", "Balmer");person.setPersonId(1L);session.save(person);

Employee employee = new Employee("James", "Gosling", "Marketing", new Date());employee.setPersonId(2L);session.save(employee);

Owner owner = new Owner("Bill", "Gates", 300L, 20L);owner.setPersonId(3L);session.save(owner);

session.getTransaction().commit();session.close();

}}

Page 15: Hibernate inheritance and relational mappings with examples

One Table Per SubclassSuppose we have a class Person with subclass Employee and Owner. Following the class diagram and relationship of these classes.

In One Table per Subclass scheme, each class persist the data in its own separate table. Thus we have 3 tables; PERSON, EMPLOYEE and OWNER to persist the class data. Note that a foreign key relationship exists between the subclass tables and super class table. Thus the common data is stored in PERSON table and subclass specific fields are stored in EMPLOYEE and OWNER tables.

Following are the advantages and disadvantages of One Table per Subclass scheme.

AdvantageUsing this hierarchy, does not require complex changes to the database schema when a single parent class is modified.It works well with shallow hierarchy.

DisadvantageAs the hierarchy grows, it may result in poor performance.The number of joins required to construct a subclass also grows.

Page 16: Hibernate inheritance and relational mappings with examples

One Table Per SubclassExample:package com.chetu.training;import javax.persistence.*;

@Entity@Table(name = "PERSON")@Inheritance(strategy=InheritanceType.JOINED)public class Person {

@Id@GeneratedValue@Column(name = "PERSON_ID")private Long personId;

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

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

public Person() {}public Person(String firstname, String lastname) {

this.firstname = firstname;this.lastname = lastname;

}// Getter and Setter methods,

}

Page 17: Hibernate inheritance and relational mappings with examples

One Table Per Subclass

The Person class is the root of hierarchy. Hence we have used some annotations to make it as the root.

@Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

@InheritanceType – Defines inheritance strategy options. JOINED is a strategy in which fields that are specific to a subclass are mapped to a separate table than the fields that are common to the parent class, and a join is performed to instantiate the subclass. Thus fields of Employee (joining_date, department) and Owner (stocks etc) are mapped to their respective tables.

Page 18: Hibernate inheritance and relational mappings with examples

One Table Per SubclassExamplepackage com.chetu.training

import java.util.Date;

import javax.persistence.*;@Entity@Table(name="EMPLOYEE")@PrimaryKeyJoinColumn(name="PERSON_ID")public class Employee extends Person {

@Column(name="joining_date")private Date joiningDate;

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

public Employee() {}

public Employee(String firstname, String lastname, String departmentName, Date joiningDate) {super(firstname, lastname);

this.departmentName = departmentName;this.joiningDate = joiningDate;

}// Getter and Setter methods,

}

Page 19: Hibernate inheritance and relational mappings with examples

One Table Per SubclassExamplePackage com.chetu.training;

import javax.persistence.*;

@Entity@Table(name="OWNER")@PrimaryKeyJoinColumn(name="PERSON_ID")public class Owner extends Person {

@Column(name="stocks")private Long stocks;

@Column(name="partnership_stake")private Long partnershipStake;

public Owner() {}

public Owner(String firstname, String lastname, Long stocks, Long partnershipStake) {

super(firstname, lastname);

this.stocks = stocks;this.partnershipStake = partnershipStake;

}

// Getter and Setter methods, }

Page 20: Hibernate inheritance and relational mappings with examples

One Table Per Subclass

Both Employee and Owner classes are child of Person class. Thus while specifying the mappings, we used @PrimaryKeyJoinColumn to map it to parent table.

@PrimaryKeyJoinColumn – This annotation specifies a primary key column that is used as a foreign key to join to another table.

It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.

If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass.

Page 21: Hibernate inheritance and relational mappings with examples

One Table Per SubclassExample:

Package com.chetu.training;

import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;

public class Main {public static void main(String[] args) {

SessionFactory sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();session.beginTransaction();

Person person = new Person("Steve", "Balmer");session.save(person);

Employee employee = new Employee("James", "Gosling", "Marketing", new Date());session.save(employee);

Owner owner = new Owner("Bill", "Gates", 300L, 20L);session.save(owner);

session.getTransaction().commit();session.close();

}}

Page 22: Hibernate inheritance and relational mappings with examples

Hibernate Mappings

Hibernate supports the following Mappings as the relational database supports:

1.One to One2.Many to One3.Many to Many.

Page 23: Hibernate inheritance and relational mappings with examples

One to One mappingExample: package com.chetu.training;import java.sql.Date;import javax.persistence.*;

@Entity@Table(name="EMPLOYEE")public class Employee {

@Id@GeneratedValue@Column(name="employee_id")private Long employeeId;

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

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

@Column(name="birth_date")private Date birthDate;

Page 24: Hibernate inheritance and relational mappings with examples

One to One mapping

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

@OneToOne(mappedBy="employee", cascade=CascadeType.ALL)private EmployeeDetail employeeDetail;

public Employee() {}public Employee(String firstname, String lastname, Date birthdate, String phone) {

this.firstname = firstname;this.lastname = lastname;this.birthDate = birthdate;this.cellphone = phone;

}// Getter and Setter methods

}

Page 25: Hibernate inheritance and relational mappings with examples

One to One mappingExample:package com.chetu.training;import javax.persistence.*;import org.hibernate.annotations.*

@Entity@Table(name="EMPLOYEEDETAIL")public class EmployeeDetail {

@Id@Column(name="employee_id", unique=true, nullable=false)@GeneratedValue(generator="gen")@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="employee"))private Long employeeId;

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

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

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

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

Page 26: Hibernate inheritance and relational mappings with examples

One to One mapping

@OneToOne@PrimaryKeyJoinColumnprivate Employee employee;

public EmployeeDetail() {

}

public EmployeeDetail(String street, String city, String state, String country) {this.street = street;this.city = city;this.state = state;this.country = country;

}

// Getter and Setter methods}

Page 27: Hibernate inheritance and relational mappings with examples

One to One mappingExample:package com.chetu.training;import java.sql.Date;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;

public class Main {public static void main(String[] args) {SessionFactory sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();session.beginTransaction();

EmployeeDetail employeeDetail = new EmployeeDetail("10th Street", "LA", "San Francisco", "U.S.");Employee employee = new Employee("Nina", "Mayers", new Date(121212),"114-857-965");employee.setEmployeeDetail(employeeDetail);employeeDetail.setEmployee(employee);

session.save(employee);

List<Employee> employees = session.createQuery("from Employee").list();for (Employee employee1 : employees) {

System.out.println(employee1.getFirstname() + " , "+ employee1.getLastname() + ", "+ employee1.getEmployeeDetail().getState());}session.getTransaction().commit();session.close();

}}

Page 28: Hibernate inheritance and relational mappings with examples

One to Many or Many to One mapping

Example:Package com.chetu.training;import java.sql.Date;import javax.persistence.*;

@Entity@Table(name="EMPLOYEE")public class Employee {

@Id@GeneratedValue@Column(name="employee_id")private Long employeeId;

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

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

@Column(name="birth_date")private Date birthDate;

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

Page 29: Hibernate inheritance and relational mappings with examples

One to Many or Many to One mapping

@ManyToOne@JoinColumn(name="department_id")private Department department;

public Employee() {

}

public Employee(String firstname, String lastname, String phone) {this.firstname = firstname;this.lastname = lastname;this.birthDate = new Date(System.currentTimeMillis());this.cellphone = phone;

}

// Getter and Setter methods}

Page 30: Hibernate inheritance and relational mappings with examples

One to Many or Many to One mapping

Example:@ManyToOne annotation defines a single-valued association to another entity class that has many-to-one multiplicity. It is not normally necessary to specify the target entity explicitly since it can usually be inferred from the type of the object being referenced.@JoinColumn is used to specify a mapped column for joining an entity association.

Package com.chetu.training;import java.util.Set;import javax.persistence.*;

@Entity@Table(name="DEPARTMENT")public class Department {

@Id@GeneratedValue@Column(name="DEPARTMENT_ID")private Long departmentId;

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

@OneToMany(mappedBy="department")private Set<Employee> employees;// Getter and Setter methods

}

Page 31: Hibernate inheritance and relational mappings with examples

One to Many or Many to One mapping

@OneToMany annotation defines a many-valued association with one-to-many multiplicity.If the collection is defined using generics to specify the element type, the associated target entity type need not be specified; otherwise the target entity class must be specified.

The association may be bidirectional. In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side. In our case, this is passport. As you can see, you don’t have to (must not) declare the join column since it has already been declared on the owners side.

Page 32: Hibernate inheritance and relational mappings with examples

One to Many or Many to One mapping

Example:Package com.chetu.training;import org.hibernate.Session;import org.hibernate.SessionFactory;

public class Main {public static void main(String[] args) {SessionFactory sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();session.beginTransaction();

Department department = new Department();department.setDepartmentName("Sales");session.save(department);

Employee emp1 = new Employee("Nina", "Mayers", "111");Employee emp2 = new Employee("Tony", "Almeida", "222");

emp1.setDepartment(department);emp2.setDepartment(department);

session.save(emp1);session.save(emp2);

session.getTransaction().commit();session.close();

}}

Page 33: Hibernate inheritance and relational mappings with examples

Many to Many mapping

Example:package net.viralpatel.hibernate;

import java.util.HashSet;import java.util.Set;import javax.persistence.*;@Entity@Table(name="EMPLOYEE")public class Employee {

@Id@Column(name="EMPLOYEE_ID")@GeneratedValueprivate Long employeeId;

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

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

Page 34: Hibernate inheritance and relational mappings with examples

Many to Many mapping

@ManyToMany(cascade = {CascadeType.ALL})@JoinTable(name="EMPLOYEE_MEETING",

joinColumns={@JoinColumn(name="EMPLOYEE_ID")}, inverseJoinColumns={@JoinColumn(name="MEETING_ID")})

private Set<Meeting> meetings = new HashSet<Meeting>();

public Employee() {}

public Employee(String firstname, String lastname) {this.firstname = firstname;this.lastname = lastname;

}// Getter and Setter methods

}

Page 35: Hibernate inheritance and relational mappings with examples

Many to Many mappingPackage com.chetu.training;

import java.util.Date;import java.util.HashSet;import java.util.Set;import javax.persistence.*;@Entity@Table(name="MEETING")public class Meeting {

@Id@Column(name="MEETING_ID")@GeneratedValueprivate Long meetingId;

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

@Column(name="MEETING_DATE")private Date meetingDate;

}

Page 36: Hibernate inheritance and relational mappings with examples

Many to Many mapping

@ManyToMany(mappedBy="meetings")private Set<Employee> employees = new HashSet<Employee>();

public Meeting(String subject) {this.subject = subject;this.meetingDate = new Date();

}

// Getter and Setter methods}

Page 37: Hibernate inheritance and relational mappings with examples

Many to Many mappingLet us understand the annotations we used here to map Many to many relationship.

@ManyToMany – Is used to create many-to-many relationship between Employee and Meeting entities. If the Collection is defined using generics to specify the element type, the associated target entity class does not need to be specified; otherwise it must be specified. Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. The join table is specified on the owning side. If the association is bidirectional, either side may be designated as the owning side.

Note that in above entity classes, Employee is defined as relationship owner as @JoinColumn is define in Employee class and mappedBy is specified in Meeting class.

@JoinTable – Is used to define the join table (link table) for many-to-many relationship. It is specified on the owning side of a many-to-many association, or in a unidirectional one-to-many association. In this case the join table is EMPLOYEE_MEETING.

If the JoinTable annotation is missing, the default values of the annotation elements apply. The name of the join table is assumed to be the table names of the associated primary tables concatenated together (owning side first) using an underscore.

@JoinColumn – Is used to define the join column (linking column) in both main tables.

Page 38: Hibernate inheritance and relational mappings with examples

Many to Many mapping

Note: that we have used SET to map meetings with employee and vice versa. A <set> is similar to except that it can only store unique objects. That means no duplicate elements can be contained in a set. When you add the same element to a set for second time, it will replace the old one. A set is unordered by default but we can ask it to be sorted. The corresponding type of a <set> in Java is java.util.Set.

Page 39: Hibernate inheritance and relational mappings with examples

Many to Many mappingExample: package com.chetu.training;import org.hibernate.Session;import org.hibernate.SessionFactory; public class Main { public static void main(String[] args) { SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); Meeting meeting1 = new Meeting("Quaterly Sales meeting"); Meeting meeting2 = new Meeting("Weekly Status meeting"); Employee employee1 = new Employee("Sergey", "Brin"); Employee employee2 = new Employee("Larry", "Page");

employee1.getMeetings().add(meeting1); employee1.getMeetings().add(meeting2); employee2.getMeetings().add(meeting1); session.save(employee1); session.save(employee2); session.getTransaction().commit(); session.close(); }}


Recommended