Hibernate ORM

Hibernate Example with Annotations

Create a Maven-based Hibernate application that maps an Employee entity to a database table without an XML mapping file.

Hibernate Annotation Example

Hibernate annotations provide metadata directly in Java source code. They are based on the Jakarta Persistence specification and remove the need for a separate Hibernate mapping file for common entity mappings.

@Entity

Marks a class as a persistent entity.

@Table

Customizes the database table name.

@Id

Identifies the primary-key property.

@Column

Customizes a column name and constraints.

@GeneratedValue

Defines how an identifier is generated.

@Transient

Excludes a property from persistence.

Package note: Hibernate 6 uses jakarta.persistence. Older Hibernate 5 applications commonly use javax.persistence. Do not mix the two namespaces in one application.

1. Create a Maven Project

Create a standard Maven project in your IDE or from the command line. A simple structure looks like this:

hibernate-annotation-demo/
  pom.xml
  src/main/java/com/example/Employee.java
  src/main/java/com/example/StoreData.java
  src/main/resources/hibernate.cfg.xml

2. Configure Maven Dependencies

Add Hibernate ORM and a JDBC driver to pom.xml. Maven downloads Hibernate's transitive dependencies automatically.

<properties>
  <maven.compiler.release>17</maven.compiler.release>
  <hibernate.version>6.6.9.Final</hibernate.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
  <version>${hibernate.version}</version>
  </dependency>
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.3.232</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

H2 keeps this example self-contained. For MySQL or PostgreSQL, replace H2 with the corresponding JDBC driver and update the connection settings. Avoid adding old or manually downloaded Oracle driver artifacts unless your project has a licensed, compatible driver.

3. Create the Persistent Entity

The entity below maps Java fields to the employee table. A no-argument constructor is required by Hibernate, and the generated identifier is assigned when the entity is persisted.

package com.example;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name", nullable = false)
    private String lastName;

    protected Employee() {
        // Required by Hibernate.
    }

    public Employee(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Long getId() { return id; }
    public String getFirstName() { return firstName; }
    public String getLastName() { return lastName; }
}

4. Create the Hibernate Configuration

Place hibernate.cfg.xml in src/main/resources. The mapping class element registers the annotated entity.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">org.h2.Driver</property>
    <property name="hibernate.connection.url">jdbc:h2:mem:company;DB_CLOSE_DELAY=-1</property>
    <property name="hibernate.connection.username">sa</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
    <property name="hibernate.hbm2ddl.auto">create-drop</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <mapping class="com.example.Employee"/>
  </session-factory>
</hibernate-configuration>

create-drop creates the table for the example and removes it when the factory closes. Use migrations such as Flyway or Liquibase for production schema management.

5. Store the Persistent Object

Open a session, begin a transaction, persist an Employee, and commit. The transaction rollback protects the database if the operation fails.

package com.example;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class StoreData {
    public static void main(String[] args) {
        try (SessionFactory factory = new Configuration()
                .configure()
                .buildSessionFactory();
             Session session = factory.openSession()) {

            Transaction transaction = session.beginTransaction();
            try {
                Employee employee = new Employee("Gaurav", "Chawla");
                session.persist(employee);
                transaction.commit();
                System.out.println("Employee saved with id: " + employee.getId());
            } catch (RuntimeException exception) {
                transaction.rollback();
                throw exception;
            }
        }
    }
}

6. Run the Application

From the project directory, compile and run the class using Maven:

mvn compile
mvn exec:java -Dexec.mainClass="com.example.StoreData"

If your IDE runs the class directly, make sure src/main/resources is on the runtime classpath. Hibernate should create the table, execute an INSERT, and print the generated identifier.

Expected result: an employee is inserted into the employee table and the console prints a message similar to Employee saved with id: 1.

How the Annotations Work

AnnotationPurpose
@EntityDeclares that the class can be persisted.
@Table(name = "employee")Maps the entity to a specific table. Without it, the provider derives a table name.
@IdMarks the primary-key attribute.
@GeneratedValueDelegates identifier generation to the selected strategy and database.
@ColumnCustomizes a column name and constraints such as nullable.

Common Problems

  • Entity not found: verify the mapping class entry or package scanning configuration.
  • Driver error: confirm that the JDBC driver is in the runtime dependencies.
  • Namespace error: use jakarta.persistence with Hibernate 6 and javax.persistence only with a matching older stack.
  • Table changes are unexpected: replace development-only schema generation with a database migration tool.
  • Resource leaks: close the Session and SessionFactory, preferably with try-with-resources.