JPA Entities & Mapping
A JPA entity is a plain Java class that maps to a database table. With a handful of annotations — @Entity , @Id , @GeneratedValue , @Column , @Table — you describe how objects become rows and back again.
Learn JPA Entities & Mapping in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You should understand classes and objects and the basics of Spring Data JPA . These examples use the jakarta.persistence annotations.
What You'll Learn
The Big Idea — A Form That Fills a Spreadsheet Row
💡 Analogy: Think of an @Entity class as a paper form and the database table as a spreadsheet . Each field on the form is a column; each filled-in form becomes one row. @Id is the row number, @GeneratedValue means the spreadsheet stamps that number for you, and @Column notes are the rules ("this box can't be blank, max 100 characters"). You design the form once; the framework files every submission as a tidy row.
Object-relational mapping is just this translation: objects to rows, rows to objects, automatically.
1️⃣ A Basic Entity
Annotate a class with @Entity , mark its key with @Id , and let the database generate ids. @Table and @Column fine-tune the names and constraints.
2️⃣ How a Generated Id Behaves
With @GeneratedValue , the id is null until the row is inserted ; the database then assigns the value. Here is a plain-Java simulation of that lifecycle you can actually run.
3️⃣ Keeping Fields Out — @Transient
JPA persists every field by default. A value you only compute in memory — a formatted price, a cached total — should be marked @Transient so it never becomes a column.
🧠 Quick Recall
Answer: Invoice — JPA derives the table name from the entity name unless @Table(name = "...") overrides it.
Answer: null for a generated Long id — the database assigns it on insert.
Answer: @Transient . The field stays in memory only and is never mapped to a column.
🎯 YOUR TURN — Map a Book
Create a Book entity with a generated id, a NOT NULL title, and a unique isbn_13 column.
🧩 MINI-CHALLENGE — Employee with a derived field
Map an Employee with custom column names and a @Transient computed salary.
Common Errors
- ❌ No no-arg constructor. The provider can't instantiate the entity. Fix: add a protected or public no-arg constructor.
- ❌ Forgetting @Id. Every entity needs a primary key. Fix: mark exactly one field (or composite) with @Id .
- ❌ Using a primitive for a generated id. It can't be null before insert. Fix: use Long , not long .
- ❌ Storing money as double. Rounding bugs creep in. Fix: store integer cents or use BigDecimal.
- ❌ Persisting computed fields. Derived values bloat the table. Fix: mark them @Transient .
- ❌ Mixing javax and jakarta imports. Modern Spring Boot uses jakarta.persistence . Fix: import from jakarta , not javax .
Pro Tips
- 💡 Use wrapper types for ids ( Long ) so a not-yet-saved entity reads as null .
- 💡 Add explicit @Column constraints — nullable , length , unique — to shape the generated schema.
- 💡 Keep a protected no-arg constructor for JPA and a real constructor for your own code.
- 💡 Prefer IDENTITY or SEQUENCE over assigning ids by hand in application code.
📋 Quick Reference
Annotation
Purpose
Note
@Entity
class is persistent
Maps to a table
@Table(name)
custom table name
Defaults to class name
@Id
primary key
Exactly one
@GeneratedValue
auto-generate key
IDENTITY / SEQUENCE
@Column(name)
custom column name
Defaults to field
@Column(nullable)
NOT NULL constraint
false = required
@Column(length)
VARCHAR size
For String columns
@Column(unique)
UNIQUE constraint
No duplicates
@Transient
not persisted
In-memory only
no-arg ctor
required by JPA
protected is fine
📚 Resources / Keep Learning
- 📘 Jakarta Persistence 3.1 specification (jakarta.ee)
- 📗 Spring Data JPA — entity persistence (docs.spring.io)
- 📗 Hibernate ORM documentation (hibernate.org)
❓ Frequently Asked Questions
🎉 Lesson Complete!
You can now map a class to a table with @Entity , define and auto-generate a primary key with @Id and @GeneratedValue , shape columns and tables with @Column and @Table , and exclude computed fields with @Transient .
Next up: Entity Relationships — connecting entities with @OneToMany , @ManyToOne , and @ManyToMany .
Practice quiz
What does the @Entity annotation mark a class as?
- A REST controller
- A JPA-managed persistent entity mapped to a table
- A Spring bean only
- A configuration file
Answer: A JPA-managed persistent entity mapped to a table. @Entity tells JPA the class maps to a database table and its instances are persistent entities.
Which annotation marks the primary key field of an entity?
- @Key
- @Primary
- @Id
- @Column(primary=true)
Answer: @Id. @Id designates the field that maps to the table's primary key.
What does @GeneratedValue(strategy = GenerationType.IDENTITY) do?
- Generates a random UUID in Java
- Lets the database auto-increment the key column
- Disables key generation
- Uses a table to store keys only
Answer: Lets the database auto-increment the key column. IDENTITY delegates key generation to the database's own auto-increment column.
By default, what table name does JPA use for an @Entity class named Customer?
- customers
- tbl_Customer
- Customer
- entity_customer
Answer: Customer. Without @Table, JPA derives the table name from the entity name, here Customer.
Which annotation overrides the default table name for an entity?
- @Table(name = "...")
- @Entity(table = "...")
- @MapTo
- @Schema
Answer: @Table(name = "..."). @Table(name = "...") sets an explicit table name, useful when it differs from the class name.
What does @Column(nullable = false) enforce?
- The column is the primary key
- The column is unique
- The column is indexed
- The column may not store NULL
Answer: The column may not store NULL. nullable = false adds a NOT NULL constraint to the generated column.
A no-argument constructor is required on a JPA entity because...
- Java forbids other constructors
- The persistence provider instantiates entities reflectively
- It speeds up queries
- It is needed for equals()
Answer: The persistence provider instantiates entities reflectively. JPA providers create entity instances via a no-arg constructor before populating fields.
What is the effect of @Column(length = 100) on a String field?
- Limits the Java String length at runtime
- Truncates reads to 100 chars
- Sets the VARCHAR length in the generated DDL
- Indexes the first 100 characters
Answer: Sets the VARCHAR length in the generated DDL. length controls the column size (e.g. VARCHAR(100)) in the schema DDL.
If you omit @Column on a mapped field, JPA will...
- Skip the field entirely
- Throw an exception at startup
- Map it using the field name and default settings
- Treat it as transient
Answer: Map it using the field name and default settings. Persistent fields are mapped automatically; @Column is only needed to customize the mapping.
Which annotation tells JPA NOT to persist a particular field?
- @Transient
- @Ignore
- @Skip
- @NotPersisted
Answer: @Transient. @Transient marks a field as non-persistent so JPA leaves it out of the table mapping.
Continue this course
- Previous: Spring Data JPA Basics
- Next: Entity Relationships