Your First Hibernate Entity
Build a simple @Entity class, map it correctly, and save your first row using a Session.
Introduction
It is time to build something real. This lesson walks through creating a genuinely simple @Entity class from scratch, wiring it into your configuration, and saving your very first row through Hibernate, end to end.
- The minimum requirements for a class to be a valid Hibernate entity.
- How to write and annotate a simple entity class.
- How to register that entity with Hibernate.
- How to open a Session and persist your first row.
What Makes a Class an Entity?
A Hibernate entity has a few strict requirements. Meeting them is what allows Hibernate to instantiate, populate, and persist the class correctly.
@Entity Annotation
Marks the class as something Hibernate should manage and map to a table.
An @Id Field
Every entity needs exactly one field marked as its primary key.
A No-Argument Constructor
Hibernate needs to instantiate the class using reflection.
Non-Final Class
The class must not be final, since Hibernate may create proxy subclasses.
Writing the Entity Class
Here is a complete, minimal Student entity. Note the no-argument constructor, the @Id field, and standard getters and setters.
import jakarta.persistence.Entity;import jakarta.persistence.Id;
@Entitypublic class Student {
@Id private Long id;
private String name;
private String email;
public Student() { // required no-argument constructor }
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }}By default, Hibernate maps the class name directly to a table name ("Student") and each field to a column of the same name, unless you override this with @Table and @Column — covered in the next lesson.
Registering the Entity
The entity must be registered so Hibernate's Configuration knows about it, either in hibernate.cfg.xml or programmatically.
<mapping class="com.programinds.Student"/>Configuration configuration = new Configuration() .configure("hibernate.cfg.xml") .addAnnotatedClass(Student.class);Opening a Session and Saving
With the entity registered, saving a row takes just a few lines: open a Session, begin a Transaction, create the object, persist it, and commit.
import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;
public class Main { public static void main(String[] args) { SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
try (Session session = sessionFactory.openSession()) { Transaction transaction = session.beginTransaction();
Student student = new Student(); student.setId(1L); student.setName("Alex"); student.setEmail("alex@example.com");
session.persist(student);
transaction.commit(); }
HibernateUtil.shutdown(); }}Click Run to see what this code prints.
Verifying the Result
You can confirm the row landed in the database with a plain SQL query, outside of Hibernate entirely.
SELECT * FROM Student;Click Run to see what this code prints.
This confirms the full round trip: a plain Java object was turned into a real database row, without a single line of SQL written by hand.
Common Mistakes
- Forgetting the no-argument constructor, which Hibernate requires to instantiate the entity.
- Missing the @Id annotation entirely, which causes a mapping exception at startup.
- Forgetting to register the entity class in configuration before using it.
- Calling session.persist() without an open transaction, or forgetting to commit.
Best Practices
- Start every new entity with the smallest possible set of fields, then grow it incrementally.
- Always provide a no-argument constructor, even if you add other constructors later.
- Keep entity classes focused on data — avoid putting business logic inside them.
- Verify new mappings with a simple save-and-query test before building more features on top.
Frequently Asked Questions
It is a common convention and recommended for entities that may be cached or passed across a network, but it is not strictly required by Hibernate itself.
Hibernate's native Session.save() still exists, but persist() is the standard JPA method and is the recommended, portable choice going forward.
With a manually assigned identifier like this example, Hibernate throws an exception because it cannot insert a row without a primary key value. The next lesson on primary keys covers letting the database generate this automatically.
Only if hibernate.hbm2ddl.auto is set to create, update, or a similar value, as covered in the configuration lesson. Otherwise, the table must already exist.
Key Takeaways
- A valid entity needs @Entity, an @Id field, and a no-argument constructor.
- Entities must be registered with Configuration before Hibernate can use them.
- session.persist() inside a transaction saves a new entity as a row.
- By default, class and field names map directly to table and column names.
Summary
You just completed your first full Hibernate round trip: a plain Java class became a mapped entity, and a Session turned an object into a real database row. Next, you will look more closely at the core mapping annotations — @Entity, @Table, @Column, and @Id — and what each one controls.