Getting Started
generator-blog.notes
hibernate.notes


Hibernate is an object-relational persistence framework which maps plain old Java objects (POJOs) to relational database tables, and transforms the data from one representation to the other.

Metadata (specified using annotations or XML) maps the fields of a class to the columns of a table so that a persisted instance of the class is represented by a row in the table.

The SQL required to update and query the database is automatically generated by Hibernate, so the developer no longer needs to write repetitive CRUD style SQL statements by hand.

Hibernate consists of these components:
  • Metadata to describe the mapping between classes and tables.
  • An API for CRUD operations on the objects of persistent classes.
  • A query language and API.
  • Transaction management and optimization functions.
Hibernate 3.5+ implements the Java Persistence API (JPA) 2.0 specification.
using-lishys-notes.notes

Guide


The guide pane on the right contains information organized into sections.

Use the and buttons to move through the sections, or click an accordion tab (shown below) to go directly to a particular topic.



Code Reference


Each paragraph in the guide is usually associated with a particular piece of code. An orange arrow indicates that the code displayed in the middle pane is relevant to the guide text.



If the arrow is gray, simply click anywhere on the paragraph and the relevant code will be displayed.



Code Highlighter


The highlight feature identifies areas of the code which relate to a word or term in the guide. Hover the mouse over any underlined word and the relevant code will be highlighted.



You can disable the highlighting feature at any time by clicking on the button.

Don't forget to make the appropriate code page visible by clicking on any paragraph with a gray arrow.
world-entities.jpg
world-schema.png
create-city.sql
CREATE TABLE city (
  city_id         NUMBER,
  city_name       VARCHAR2(50)  NOT NULL,
  ctry_id         NUMBER        NOT NULL,
  CONSTRAINT city_pk  PRIMARY KEY (city_id),
  CONSTRAINT city_fk1 FOREIGN KEY (ctry_id) REFERENCES ctry
  
);

CREATE SEQUENCE city_seq1;
CREATE OR REPLACE TRIGGER city_trg1
  BEFORE INSERT ON city FOR EACH ROW
BEGIN 
    IF :NEW.city_id IS NULL THEN
      SELECT city_seq1.NEXTVAL INTO :NEW.city_id FROM DUAL;
    END IF;
END;
/

INSERT INTO city (city_name, ctry_id)  VALUES('Berlin', 1);
INSERT INTO city (city_name, ctry_id)  VALUES('Hamburg', 1);
INSERT INTO city (city_name, ctry_id)  VALUES('Munich', 1);
INSERT INTO city (city_name, ctry_id)  VALUES('Accra', 2);
INSERT INTO city (city_name, ctry_id)  VALUES('Kumasi', 2);
INSERT INTO city (city_name, ctry_id)  VALUES('Tamale', 2);
INSERT INTO city (city_name, ctry_id)  VALUES('Aukland', 6);
INSERT INTO city (city_name, ctry_id)  VALUES('Christchurch', 6);
INSERT INTO city (city_name, ctry_id)  VALUES('Wellington', 6);
COMMIT;

create-continent.sql
CREATE TABLE cont (
  cont_id         NUMBER,
  cont_name       VARCHAR2(50)  NOT NULL,
  CONSTRAINT cont_pk  PRIMARY KEY (cont_id),
  CONSTRAINT cont_uk1 UNIQUE (cont_name)
);

CREATE SEQUENCE cont_seq1;
CREATE OR REPLACE TRIGGER cont_trg1
  BEFORE INSERT ON cont FOR EACH ROW
BEGIN 
    IF :NEW.cont_id IS NULL THEN
      SELECT cont_seq1.NEXTVAL INTO :NEW.cont_id FROM DUAL;
    END IF;
END;
/

INSERT INTO cont (cont_name) VALUES('Africa');
INSERT INTO cont (cont_name) VALUES('Asia');
INSERT INTO cont (cont_name) VALUES('Europe');
INSERT INTO cont (cont_name) VALUES('North America');
INSERT INTO cont (cont_name) VALUES('South America');
INSERT INTO cont (cont_name) VALUES('Oceania');
INSERT INTO cont (cont_name) VALUES('Antarctica');
COMMIT;
create-country.sql
CREATE TABLE ctry (
  ctry_id         NUMBER,
  ctry_name       VARCHAR2(50)  NOT NULL,
  ctry_area       NUMBER        NOT NULL,
  ctry_pop        NUMBER        NOT NULL,
  cont_id         NUMBER        NOT NULL,
  CONSTRAINT ctry_pk  PRIMARY KEY (ctry_id),
  CONSTRAINT ctry_uk1 UNIQUE (ctry_name),
  CONSTRAINT ctry_fk1 FOREIGN KEY (cont_id) REFERENCES cont
  
);

CREATE SEQUENCE ctry_seq1;
CREATE OR REPLACE TRIGGER ctry_trg1
  BEFORE INSERT ON ctry FOR EACH ROW
BEGIN 
    IF :NEW.ctry_id IS NULL THEN
      SELECT ctry_seq1.NEXTVAL INTO :NEW.ctry_id FROM DUAL;
    END IF;
END;
/

INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Germany', 137847, 82046000, 3);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Ghana', 92098, 23837000, 1);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Australia', 2966200, 21884000, 6);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Greece', 50949, 11257285, 3);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Georgia', 26900, 4382100, 3);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('New Zealand', 104454, 4320300, 6);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Gambia', 4361, 1705000, 1);
INSERT INTO ctry (ctry_name, ctry_area, ctry_pop, cont_id)
  VALUES('Gabon', 103347, 1475000, 1);
COMMIT;

create-world.sql
@reset-world.sql
@create-continent.sql
@create-country.sql
@create-city.sql

reset-world.sql
DROP TABLE city;
DROP TABLE ctry;
DROP TABLE cont;

DROP SEQUENCE cont_seq1;
DROP SEQUENCE ctry_seq1;
DROP SEQUENCE city_seq1;
City.java
package com.lishman.world.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;

@Entity
public class City implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "CITY_ID_GENERATOR", sequenceName = "CITY_SEQ1")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CITY_ID_GENERATOR")
    @Column(name = "CITY_ID")
    private Integer id;

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

    @ManyToOne
    @JoinColumn(name = "CTRY_ID")
    private Country country;

    public City() {
    }

    public Integer getId() {
        return this.id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Country getCountry() {
        return this.country;
    }
    public void setCountry(Country country) {
        this.country = country;
    }

}
Continent.java
package com.lishman.world.domain;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "CONT")
public class Continent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "CONT_ID_GENERATOR", sequenceName = "CONT_SEQ1")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CONT_ID_GENERATOR")
    @Column(name = "CONT_ID")
    private Integer id;

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

    @OneToMany(mappedBy = "continent")
    private Set<Country> countries;

    public Continent() {
    }
    public Integer getId() {
        return this.id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Country> getCountries() {
        return this.countries;
    }
    public void setCountries(Set<Country> countries) {
        this.countries = countries;
    }

}
Country.java
package com.lishman.world.domain;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "CTRY")
public class Country implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name = "CTRY_ID_GENERATOR", sequenceName = "CTRY_SEQ1")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CTRY_ID_GENERATOR")
    @Column(name = "CTRY_ID")
    private Integer id;

    @Column(name = "CTRY_AREA")
    private Integer area;

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

    @Column(name = "CTRY_POP")
    private Integer population;

    @OneToMany(mappedBy = "country")
    private Set<City> cities;

    @ManyToOne
    @JoinColumn(name = "CONT_ID")
    private Continent continent;

    public Country() {
    }

    public Integer getId() {
        return this.id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getArea() {
        return this.area;
    }
    public void setArea(Integer area) {
        this.area = area;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPopulation() {
        return this.population;
    }
    public void setPopulation(Integer population) {
        this.population = population;
    }
    public Set<City> getCities() {
        return this.cities;
    }
    public void setCities(Set<City> cities) {
        this.cities = cities;
    }
    public Continent getContinent() {
        return this.continent;
    }
    public void setContinent(Continent continent) {
        this.continent = continent;
    }
}
ContinentAccess.java
package com.lishman.world;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

import com.lishman.world.domain.Continent;
import com.lishman.world.domain.Country;

public class ContinentAccess {
    
    public static void main(String[] args) {
        
        EntityManager em = Persistence
                            .createEntityManagerFactory("world")
                            .createEntityManager();
                
        // find
        Continent europe = em.find(Continent.class, 3);
     
        Country ghana = em.find(Country.class, 2);
        String name = ghana.getContinent().getName();
        
        
        // persist
        em.getTransaction().begin();    
   
        Continent cont = new Continent();
        cont.setName("New Continent");
        em.persist(cont);
        int contId = cont.getId();

        em.getTransaction().commit();

        
        // update
        em.getTransaction().begin();

        Continent oceania = em.find(Continent.class, 6);
        oceania.setName("Australasia");

        em.getTransaction().commit();

        
        // remove
        em.getTransaction().begin();

        Continent newCont = em.find(Continent.class, contId);
        em.remove(newCont);

        em.getTransaction().commit();
        
        
        em.close();

    }
}

orm.xml
<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 version="1.0"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
</entity-mappings>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             version="1.0"
             xsi:schemaLocation="
           http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
                
  <persistence-unit name="world">

    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    
    <class>com.lishman.world.domain.Country</class>
    <class>com.lishman.world.domain.Continent</class>
    <class>com.lishman.world.domain.City</class>
    
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
        <property name="hibernate.connection.url" value="jdbc:oracle:thin:@my_server:1521:my_db"/>
        <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
        <property name="hibernate.connection.username" value="my_user"/>
        <property name="hibernate.connection.password" value="my_password"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
    </properties>
    
  </persistence-unit>
</persistence>

Entities

Overview of Hibernate.

Suppose we have these three tables in our schema:
  • CONT (Continent)
  • CTRY (Country)
  • CITY (City)
These tables are mapped to three equivalent JPA entities.

Entities are simply POJO classes that have been marked with the @Entity annotation.

For example, Continent is an entity that has been mapped to the CONTCONT:eq(0) table.

The two properties on the class are mapped to the columnsCONT_:gt(2) of the table.
@Id designates the annotated field as a primary key.

@GeneratedValue specifies how this value is to be generated. Because we are using an Oracle database, we referenceCONT_ID_GENERATOR a sequenceCONT_SEQ1 to allocate a incrementing value.
The sequencecont_seq1:eq(0) has already been created when the schema was built.
This blog entry has more information on auto generated primary keys in Oracle.

We can also use metadata to model the relationships between entities.
For example, the Country class has a one-to-many@OneToMany association with a City, and a many-to-one@ManyToOne association with a Continent.

See the Associations topic for more details.

Entity Manager

Persistence related operations, such as fetching, saving and deleting entities are performed by the EntityManagerEntityManager:eq(1).
To retrieve an entity from the database using a primary key, we use the findfind:lt(3):gt(0) method.

Hibernate also retrieves data for associated classes. For example, we can access the Continent for a Country, simply by navigating the object graphgetContinent.
To save a new entity on the database, we use the persistpersist:eq(3) method. However, this time we must wrap the operation in a transactiongetTransaction:lt(2).

If the persistem.persist method is successful, the saved object will contain the primary key value in the entity identifiergetId.
There is no explicit update method on EntityManager.

To permanently change the contents of an entity, simply update a persistent object (ie an object managed by the EntityManagerfind:eq(3)), and commitcommit:eq(1) the transaction.
To delete an entity, use the removeremove:eq(1) method on a managed object, within a transactiongetTransaction:gt(3).

Configuration

An EntityManagerEntityManager:eq(3) is created by an EntityManagerFactory, which is created by the PersistencePersistence:eq(1) bootstrap class.

The EntityManagerFactory is created for a named persistence unit, in this case 'world'""world"".
EntityManagerFactory searches a file called META-INF/persistence.xml for a persistence unit with the specified name""world"".

A persistence unit defines the configuration for an entity manager.
The <provider>provider specifies the class name of the persistence provider. We are using the Hibernate implementation.

The <class>class:lt(6) elements contain the fully qualified names of the classes to be included in the persistence unit.

The <properties>properties element is used to provide vendor specific properties. This allows us to define the configuration for Hibernate.
Home  |  Getting Started  |  Associations  |  Using Queries  |   lishblog  |  Email Lishy