CST 8277 Enterprise Application Programming Lecture Notes

Enterprise Application Programming (CST 8277)

Week 4

  • Topic: Jakarta Persistence with Hibernate

Hybrid Activity

  • Links in Brightspace:

    • Read Hibernate Documentation (Focus on the following topics):

    • Configuration and Setup

    • Current Session

    • Tutorial (tutorialspoint)


Lesson Summary

  • Introduction to Jakarta Persistence: Object Relational Mapping (ORM) Framework

    • Motivation: Understand the necessity of ORM in Java programming.

    • Mechanics: Explanation with examples pertaining to Hibernate and EclipseLink, which are key ORMs that influence Jakarta Persistence.


Hibernate Overview

  • Definition: Hibernate is a framework for persisting Java objects in a database.

  • Website: www.hibernate.org


Hibernate and JPA

  • Hibernate operates alongside JPA (Java Persistence API) and is compared with EclipseLink.


Learning Outcomes

  1. Understand what an ORM is.

  2. Learn how to set up Hibernate.

  3. Execute simple operations with Hibernate.


Java Persistence

  • Main Goal: Enable Java programmers to use Objects instead of database artifacts.

  • Key Question: How do we make an object persistent?

    • Answer: Create a representation of the object in a database table encompassing:

    • Corresponding table and columns

    • The number of rows and foreign-key relationships

    • Data types

    • Resulting in many questions about managing persistence in Enterprise Java, highlighting challenges like complexity, effort, and maintenance.


Object-Relational Mapping (ORM)

  • Definition: ORM maps Java objects to entities in a database, letting programmers treat databases as though they store objects.

  • Terminology:

    • Entity: A 'Person' represented by a PERSON table.

    • Attributes: Characteristics of the entity managed by table columns.

  • Mapping:

    • Entity corresponds to Class

    • Attribute corresponds to member field of Class

    • Row corresponds to an instance of Class (object)

    • Example:
      java @Entity @Table(name="myEmployee") // specifying the table name @SecondaryTable(name="moreEmployeeStuff") public class Employee {}


JDBC vs. ORM

  • JDBC (Java Database Connectivity):

    • A low-level API for executing SQL statements.

    • Requires using SQL strings and string constants for operations, e.g., "select retailer_name, curr_inv_level from regional_inventory where region = ?".

    • Issues arise when tables/columns names change; manual search and update of strings required.

  • Jakarta Persistence Framework:

    • Focuses on using objects transparently stored in relational databases.

    • Distinction: JDBC is not a persistence framework, but Hibernate uses JDBC internally for database communications.


Benefits of Hibernate

  • Simplification: Minimizes low-level SQL code.

  • ORM provision: Developers define mappings between Java classes and database tables using configuration files or Java annotations.


O/R Impedance Mismatch

  • Definition: The discrepancy between relational data and object-oriented technology results in 'object-relational impedance mismatch' (Scott Ambler).

  • Challenges: Requires expertise in Relational DB and OOP, with key skills varying from Java development and object modeling to SQL and data management.


Complexity of Relationships

  • Example of a Customer-Address relationship:

    • Simple 1:1 relationship with multiple database schemas that map this relationship, showcasing the complexity behind seemingly simple mappings.

    • Schemas Presented:

    • Several variants that illustrate different ways to manage Customer and Address entities via different database schemas with similar attributes.


Hibernate built on JDBC

  • Origin: Created by Gavin King, Hibernate works on top of JDBC.

  • Key features: It enhances productivity, maintainability, and portability of applications compared to direct JDBC usage.


Hibernate Configuration

  • Core file: The hibernate.cfg.xml external XML configuration file, enabling customization of numerous properties:

    • Sample configuration:
      xml <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hbm2ddl.auto">create</property> <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property> <property name="hibernate.connection.driver_class">org.h2.Driver</property> <property name="hibernate.connection.username">sa</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.connection.url">jdbc:h2:tcp://localhost:12345/~/test;IFEXISTS=TRUE</property> </session-factory> </hibernate-configuration>


Hibernate Example

  • Classes: Showcasing the difference between raw JDBC vs. Hibernate with an example demonstrating simpler operations using Hibernate.


Saving, Retrieving, and Querying Java Objects

  • Example Code:

  PersonPojo p1 = new PersonPojo();
  p1.setFirstName("Teddy");
  int theId = (int) session.save(p1);  // Save to DB
  PersonPojo aPerson = session.get(PersonPojo.class, theId); // Retrieve from DB
  Query query = session.createQuery("from PersonPojo");
  List<PersonPojo> persons = query.getResultList();

Hibernate Lifecycle

  • Entity States:

    1. Transient: Newly created (e.g., entity = new Entity();).

    2. Persistent: Exists in the database with changes persisting at transaction finish.

    3. Detached: Exists in memory but not associated with a Hibernate session.

  • State Changes: Transition examples between states with applicable methods (e.g., save(), delete(), update(), merge()).


Hibernate APIs Example

  • Example Configuration:

  Configuration config = new Configuration()  
    .addAnnotatedClass(Entity.class)  
    .configure("hibernate.cfg.xml");
  ServiceRegistry sR = new StandardServiceRegistryBuilder()  
    .applySettings(config.getProperties())  
    .build();
  SessionFactory factory = config.buildSessionFactory(sR);

Class as Entity

  • Entity Definition with Annotations:

  import jakarta.persistence.Entity;
  import jakarta.persistence.Id;

  @Entity
  public class Sample {
      @Id
      private int id;

      public int getId() {
          return this.id;
      }
      public void setId(int id) {
          this.id = id;
      }
  }

Improved Database Interaction

  • Transition from using point-in-time interaction to session-oriented transactions for efficient SQL handling by deferring SQL execution until transaction commit.


Hibernate Query Language (HQL)

  • Characteristics: HQL resembles SQL but operates on objects rather than tables.

  • Example Retrieval:

  Query q1 = session.createQuery("select e from Employee e where e.firstName = 'Mike'");

HQL with Joins

  • Supports complex SQL operations: Inner joins, projections, aggregations, ordering, and subqueries.

  • Example:
    Joining Employee with Address using HQL:

  Query q1 = session.createQuery("select e from Employee e where e.address.street like '%Woodroffe'");

Criteria Queries in Hibernate

  • Problem Solving: Provides an Object-Oriented query API to avoid runtime errors prevalent in string-based queries.


ORM and Performance Issues

  • Describes the N+1 problem that can arise with ORM querying where multiple SQL calls are needed to retrieve associated objects leading to inefficiency.


Lazy Loading Strategy

  • Employs hidden proxy objects between entities to delay loading of associations until necessary, optimizing database interactions and reducing round-trips.