Hibernate example using JBang

This tutorial demonstrates how to use Hibernate with JBang to execute a sample program that interacts with a database. JBang allows us to run Java programs directly from a script without the need for a full project setup. This means no Maven or Gradle configuration—just a single file with dependencies declared inline.

Prerequisites

Set Up a PostgreSQL Database: Run a PostgreSQL container using Docker:

docker run --rm --name postgresdb -e POSTGRES_USER=postgres \
   -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres -d -p 5432:5432 postgres:13

The Script

Below is a complete example of a Hibernate program that:

  1. Connects to the PostgreSQL database.
  2. Inserts a record into a table.
  3. Fetches all records from the table.
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS org.hibernate:hibernate-core:6.6.3.Final
//DEPS org.hibernate:hibernate-hikaricp:6.6.3.Final
//DEPS org.postgresql:postgresql:42.6.0
//DEPS jakarta.persistence:jakarta.persistence-api:3.1.0
//DEPS org.slf4j:slf4j-simple:2.0.9
//DEPS org.projectlombok:lombok:1.18.36
 
package com.example;

import jakarta.persistence.*;
import org.hibernate.cfg.*;
import org.hibernate.HibernateException;

import java.util.List;
import java.util.Properties;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;


public class HibernateExample {
    public static void main(String[] args) {
        // Configure Hibernate
        Configuration configuration = new Configuration();
        configuration.addAnnotatedClass(Person.class);
        configuration.setProperties(getHibernateProperties());

        // Create SessionFactory
        try (var sessionFactory = configuration.buildSessionFactory()) {
            // Open session and start transaction
            try (var session = sessionFactory.openSession()) {
                session.beginTransaction();

                // Create a new Person entity
                Person person = new Person();
                person.setName("John Doe");
                person.setAge(30);

                // Save the entity to the database
                session.persist(person);

                session.getTransaction().commit();
                System.out.println("Entity inserted: " + person);

                // Execute Named Query to fetch all records
                List<Person> persons = session.createNamedQuery("Person.findAll", Person.class).getResultList();
                System.out.println("All records in 'persons' table:");
                persons.forEach(System.out::println);
            }
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }

    private static Properties getHibernateProperties() {
        Properties props = new Properties();
        props.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
        props.setProperty("hibernate.connection.url", "jdbc:postgresql://localhost:5432/postgres");
        props.setProperty("hibernate.connection.username", "postgres");
        props.setProperty("hibernate.connection.password", "postgres");
        props.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        props.setProperty("hibernate.hbm2ddl.auto", "update"); // Updates schema but doesn't drop data
        props.setProperty("hibernate.show_sql", "true");
        props.setProperty("hibernate.format_sql", "true");
        return props;
    }

 
}


@Entity
@Table(name = "persons")
@NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p")
@Data
class Person {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	private String name;
	private int age;
}

Explanation

  1. Inline Dependencies: The //DEPS directives declare required dependencies like Hibernate, PostgreSQL driver, and SLF4J.
  2. Entity Class: The Person class is annotated with @Entity and @Table, representing a table in the database.
  3. Hibernate Configuration: Connection properties are defined programmatically in getHibernateProperties.
  4. Hibernate Operations:
    • Insert: Creates and saves a new record in the database.
    • Query: Fetches all records from the persons table using JPQL.
  5. Database Table: Hibernate will automatically create the persons table due to the hibernate.hbm2ddl.auto=update property.

Running the Script

Save the script as HibernateExample.java, then execute it with JBang:

jbang HibernateExample.java

Output

You should see output similar to this:

Hibernate: 
    insert 
    into
        persons
        (age, name) 
    values
        (?, ?)
Entity inserted: Person(id=3, name=John Doe, age=30)
Hibernate: 
    select
        p1_0.id,
        p1_0.age,
        p1_0.name 
    from
        persons p1_0
All records in 'persons' table:
Person(id=1, name=John Doe, age=30)
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

Key Benefits of Using JBang

  1. No Project Setup: Run Java code with dependencies directly from a single file.
  2. Portable and Easy: Share or execute scripts without needing Maven/Gradle configurations.
  3. Great for Prototyping: Quickly test database or Hibernate code without project overhead.
Was this article helpful? We need your support to keep MasterTheBoss alive!