DEV Community

Cover image for Getting Started with Hibernate: An Introduction to ORM and JPA Annotations
Kaweesha Marasinghe
Kaweesha Marasinghe

Posted on

1

Getting Started with Hibernate: An Introduction to ORM and JPA Annotations

In my previous blog post, we explored how databases work and delved into the differences between relational, object-oriented, and object-relational databases. If you haven’t read it yet, feel free to check it out here.

Building on that foundation, this blog will dive into Object-Relational Mapping (ORM)—a concept that bridges the gap between object-oriented programming and relational databases. Specifically, we’ll focus on how ORM frameworks like Hibernate simplify the process of mapping Java objects to database tables. This not only makes database operations more intuitive but also helps developers create and manage database structures seamlessly from their Java code. 🚀


What is ORM?

Object-Relational Mapping (ORM) is a technique used to map Java objects to database tables, making it easier to handle databases without writing raw SQL queries.

Example:

Without ORM, performing CRUD (Create, Read, Update, Delete) operations requires writing raw SQL queries like SELECT, INSERT, UPDATE, and DELETE to interact with the database.

With ORM, you can retrieve data and map it to Java objects effortlessly, eliminating the need for extensive SQL code.


Hibernate: The Go-To ORM Tool

Hibernate is an implementation of JPA (Java Persistence API). JPA is a standard specification for managing relational data, while Hibernate adheres to this specification and performs ORM operations.

Hibernate simplifies database interaction by allowing developers to write database-independent code. This means you can switch your data source with minimal changes to your application code.

Image description


Why Use Hibernate?

With Hibernate, developers can:

  • Avoid writing raw SQL queries.

  • Work with Java objects instead of relational data structures.

  • Easily switch between different databases with minimal code adjustments.


JPA Annotations in Hibernate

To handle ORM operations, Hibernate relies on JPA annotations. Below, we’ll cover 8 of the most commonly used JPA annotations that make database operations seamless.

Image description


1. @Entity 🏛️

This annotation marks a Java class as a JPA entity, which maps to a table in the database. For example, if a class called User is annotated with @Entity, Hibernate will treat it as a table in the database, with its attributes mapped to table columns.

Example:

@Entity
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
}
Enter fullscreen mode Exit fullscreen mode
  • The User class will be mapped to a table named User in the database.
  • The class attributes (id, name, email) will become columns in the table.

2. @Table 🗄️

The @Table annotation allows customization of the table name and other table-specific attributes.

By default, when a class is annotated with @Entity, the database table will have the same name as the entity class. However, if you want a different name, you can customize it using @Table.

Example:

@Entity
@Table(name = "users", schema = "public")
public class User {
    @Id
    private Long id;
    private String name;
    private String email;
}
Enter fullscreen mode Exit fullscreen mode
  • The User class is mapped to a table named users in the public schema.

3. @Id 🆔

Every entity class must have a primary key to uniquely identify records in the corresponding table. The @id annotation is used to specify which attribute serves as the primary key.

Example:

@Entity
public class User {
    @Id
    private Long id;
    private String name;
}
Enter fullscreen mode Exit fullscreen mode
  • The id field is now the primary key of the User entity and corresponds to the primary key column in the database table.

4. @GeneratedValue 🔢

The @GeneratedValue annotation specifies how the primary key value is generated. Hibernate supports four key strategies:

  1. IDENTITY: The primary key is auto-incremented, similar to SQL database behavior.
  2. SEQUENCE: Uses a database sequence to generate unique values.
  3. TABLE: Uses a separate database table to generate primary key values. This method is slower due to additional database reads.
  4. AUTO: JPA automatically selects the generation strategy based on the database dialect.

Example:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Enter fullscreen mode Exit fullscreen mode
  • In this example, the id value will be auto-incremented by the database.

5.@Column 📋

The @column annotation is used to define column-specific constraints and customize column names in the database.

Example:

@Column(name = "full_name", nullable = false, unique = true)
private String name;
Enter fullscreen mode Exit fullscreen mode
  • Maps the name field to a column named full_name.
  • The column cannot have null values (nullable = false) and must contain unique entries (unique = true).

6. @OneToMany and @ManyToOne 🔗

These annotations define relationships between entities:

  • @OneToMany: A parent entity is related to multiple child entities.
  • @ManyToOne: A child entity is related to a single parent entity.

Example: Parent-Child Relationship

Let’s say a User can have multiple Order records.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Order> orders;
}
Enter fullscreen mode Exit fullscreen mode
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;

    @ManyToOne
    @JoinColumn(name = "user_id") // Foreign key in the "orders" table
    private User user;
}
Enter fullscreen mode Exit fullscreen mode
  • @OneToMany in User indicates a list of Order entities.
  • @ManyToOne in Order links each order to a single user.
  • @JoinColumn defines the foreign key column (user_id) in the orders table.

Wrapping It All Up 🎁

Hibernate and JPA annotations make database interactions seamless, bridging the gap between Java objects and relational databases. They eliminate the need to write raw SQL queries and ensure your application remains database-independent.

In the next blog post, we’ll explore advanced Hibernate topics like caching, transactions, and best practices for optimizing performance.

Stay tuned, and happy coding! ✨

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (2)

Collapse
 
babyfishct profile image
babyfish-ct

I used JPA for more than 10 years, it cannot resolve all my problems, so finally I created my ORM

Collapse
 
kaweeshamr profile image
Kaweesha Marasinghe

Interesting I'll check that also

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay