Skip to content

Hibernate

Thomas Czogalik edited this page Apr 26, 2019 · 11 revisions

ORM (object-relational mapping) Tool

in data layer

implements JPA

maps object into relational databases and visa versa

Java Database Connectivity (JDBC)

  • provides a set of Java API for accessing the relational databases from Java program
  • APIs enables Java programs to execute SQL statements and interact with any SQL compliant database
  • database independent

Object-Relational Mapping (ORM)

  • is a programming technique for converting data between relational databases and object oriented programming languages
  • Hides details of SQL queries from OO logic.
  • No need to deal with the database implementation.
  • Transaction management and automatic key generation.

Hibernate

  • mapping Java classes to database tables using XML files
  • Provides simple APIs for storing and retrieving Java objects directly to and from the database.
  • If there is change in the database or in any table, then you need to change the XML file properties only.
  • uses JDBC

Configuration Object

  • created only once during application initialization
  • provides two keys components
    • Database Connection − This is handled through one or more configuration files supported by Hibernate. These files are hibernate.properties and hibernate.cfg.xml.
    • Class Mapping Setup − This component creates the connection between the Java classes and database tables.

SessionFactory

  • configures Hibernate
  • reads hibernate configuration file
  • creates Session objects
  • thread safe
  • one SessionFactory object per database
SessionFactory factory = new Configuration()
                         .configure("hibernate.cfg.xml")
                         .addAnnotatedClass(Student.class)
                         .buildSessionFactory();

Session

  • used to get a connection with a database
  • wraps JDBS connection
  • used to save/retrieve objects
Session session = factory.getCurrentSession();

Primary Key

  • unique id for each row in a table
  • cannot be null value

Annotations

use javax.persistence package

@Entity

  • marks class as an entity bean
  • must have a no-argument constructor (at least protected scope)

@Table

  • details of table that will be used to persist entity in database
  • 4 attributes
    • name
    • catalogue
    • schema
    • constraints

@Id

  • primary key
  • automatically determines the most appropriate primary key generation strategy
  • override generation strategy by applying @GeneratedValue
    • strategy (check database for what is supported)
      • GenerationType.AUTO: Pick appropriate strategy
      • GenerationType.IDENTITY: using database identity column (auto increment)
      • GenerationType.SEQUENCE: using database sequence
      • GenerationType.TABLE: using database table to ensure uniqueness
    • generator

@Column

  • specify details of the column to which a field or property will be mapped
  • attributes
    • name
    • length: size of the column
    • nullable
    • unique: only unique values

Create

Student student = new Student("Daffy", "Duck");

session.beginTransaction(); 

session.save(student);

session.getTransaction().commit();

Read

Session session = factory.getCurrentSession();
session.beginTransaction(); 

//by id
Student student = session.get(Student.class, student.getId());

session.getTransaction().commit();

Update

//one student
Student student = session.get(Student.class, student.getId());
student.setFirstName("Scooby");
//student is a persistent object, no need for calling a setter, getter or save method
session.getTransaction().commit();

//multiple students
session.createQuery("update Student set email='foo@gmail.com'").executeUpdate();

Delete

//one student
Student student = session.get(Student.class, student.getId());
session.delete(student);
session.getTransaction().commit();

//multiple students
session.createQuery("delete from Student where email='foo@gmail.com'").executeUpdate();

Hibernate Queury Language (HQL)

Clauses

From

load a complete persistent object

List<Student> students = session
                         .createQuery("from Student")
                         .getResultList();

As

to assign aliases to the classes in HQL queries

...
.createQuery("FROM Employee AS E")

Select

obtain few properties of objects instead of the complete object

...
.createQuery("SELECT E.firstName FROM Employee E")

Where

narrow the specific object that are returned from storage

...
.createQuery("FROM Employee E WHERE E.id = 10")

Order By

  • order the results by any property
  • ascending (ASC) or descending (DESC)
...
.createQuery("FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC")

Group By

  • group it based on a value of an attribute
  • use the result to include an aggregate value
...
.createQuery("SELECT SUM(E.salary), E.firtName FROM Employee E GROUP BY E.firstName")

Aggregate

avg(property name)

The average of a property's value

count(property name or *)

The number of times a property occurs in the results

max(property name)

The maximum value of the property values

min(property name)

The minimum value of the property values

sum(property name)

The sum total of the property values

Validation

  • validate data before persisting it to database
  • JPA provides EntityListeners
  • provide method with return type void and no arguments
  • annotate it with @PrePersist and @PreUpdate
@PrePersist
@PreUpdate
public void validateAlcoholByVolume() {
	if (alcoholByVolume == null) {
		throw new IllegalArgumentException();
	}
	if (alcoholByVolume.precision() > 3) {
		throw new IllegalArgumentException();
	}
	if (alcoholByVolume.scale() > 1) {
		throw new IllegalArgumentException();
	}
}

AttributeConverter

  • persist any Java datatype
  • implement AttributeConverter interface of JPA
    • convertToDatabaseColumn: converts your datatype into a database datatype
    • convertToEntityAttribute: converts a database datatype into your datatype
  • annotate your fields with @Convert(converter = MyAttributeConverter.class)

Optimistic Locking

  • multiple users try to update same object at same time and one will be overwritten
  • if update also update version (increment)
  • if version does not match don't update
  • annotate version field with @Version
  • if saved new entities can have null versions
  • if updated entities can not have null versions

Relationships

  • use below annotation and @JoinColumn(name = "${name.of.column}") to config the column
  • to propagate entity state changes from Parents to Child entities use cascade = CascadeType.ALL or other
  • remove orphans (objects B is bound to A. A is removed. B still lives) by adding orphanRemoval = true to relationship annotation

1:1

  • for each A max one B
  • two A instances can not share the same B instance
  • @OneToOne annotation
  • A can have a null reference to B

n:1

  • for each A max one B
  • two A instances can share the same B instance
  • @ManyToOne annotation

1:n

  • A can reference many instances of B
  • Each B can only belong to one A
  • @OneToMany annotation

m:n

  • A can reference many instances of B
  • Each B can belong to many As
  • @ManyToMany annotation

Lazy Loading

  • FetchType specifies if relationship neads to be fetched
  • EAGER: relationship will be loaded immediately
  • LAZY: relationship will be loaded on first use
  • set using attribute fetch
  • default values:
    • @OneToOne and @ManyToOne: EAGER
    • @OneToMany and @ManyToMany: LAZY
  • Objects that are loaded lazy are initialized with a proxy object
    • proxy object is a sub class of the lazy loaded objects
    • proxy object has all fields uninitialized
    • real object is loaded after first method call

Clone this wiki locally