0Pricing
Java Academy · Lesson

Entity Mapping with JPA Annotations

Define @Entity, @Table, @Id, @GeneratedValue, @Column, and @Embedded for clean entity design.

Entity Mapping with JPA Annotations is a free Java Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is JPA Entity Mapping?

JPA (Jakarta Persistence API) maps Java classes to database tables using annotations. Hibernate is the most common JPA provider. No SQL DDL required — JPA generates schemas from annotations.

@Entity and @Table

@Entity marks a class as a JPA entity. @Table customizes the table name, schema, and unique constraints. Every entity must have a no-arg constructor (can be protected).

@Entity
@Table(name = "users", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class User {
    // ...
    protected User() {} // required by JPA
}

@Id and @GeneratedValue

@Id marks the primary key field. @GeneratedValue configures auto-generation strategy: IDENTITY (DB auto-increment), SEQUENCE (DB sequence, better for bulk insert), or AUTO.

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

@Column: Customizing Columns

@Column sets column name, length, nullability, and uniqueness. Without it, the field name becomes the column name.

@Column(name = "full_name", nullable = false, length = 100)
private String name;
@Column(name = "email", unique = true, nullable = false)
private String email;
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;

@Embedded and @Embeddable

Extract a group of columns into a reusable value object annotated with @Embeddable. Use @Embedded in the entity to include its fields.

@Embeddable
public class Address {
    private String street, city, country;
    @Column(name = "zip_code") private String zipCode;
}
@Entity
public class User {
    @Embedded private Address address;
}

@Enumerated: Persisting Enums

Persist enums as their name string (STRING) or ordinal integer (ORDINAL). Always use STRING — ordinals break when enum values are reordered.

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private UserStatus status; // stored as "ACTIVE", "INACTIVE", etc.

@CreationTimestamp and @UpdateTimestamp

Hibernate-specific annotations that automatically set the timestamp on insert and update respectively — no need for manual @PrePersist.

@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;

@Transient: Excluding Fields

Fields annotated with @Transient are not persisted. Use for derived or computed fields that should not be stored in the database.

@Transient
public String getFullName() { return firstName + " " + lastName; }

@Lob: Large Objects

Use @Lob to map large text (TEXT/CLOB) or binary (BLOB) columns. PostgreSQL maps @Lob String to TEXT.

@Lob
@Column(name = "content")
private String content; // maps to TEXT in PostgreSQL

equals and hashCode Contract

JPA entities in collections must implement equals / hashCode based on the business key (not the generated ID, which is null before persist). Use @NaturalId or a UUID surrogate key.

@Override public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User u)) return false;
    return email != null && email.equals(u.email);
}
@Override public int hashCode() { return getClass().hashCode(); }

@Version for Optimistic Locking

Add a @Version field. Hibernate increments it on each update. If two transactions update the same row concurrently, the second throws OptimisticLockException.

@Version
private Long version; // auto-managed by Hibernate

Quick Check

Why should @Enumerated use STRING instead of ORDINAL?

Recap

Use @Entity/@Table for class-table mapping. @Id+@GeneratedValue for PKs. @Column for constraints. @Embedded for value objects. Always @Enumerated(STRING). Add @Version for optimistic locking.

Frequently asked questions

Is the “Entity Mapping with JPA Annotations” lesson free?

Yes — the full text of “Entity Mapping with JPA Annotations” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.

What will I learn in “Entity Mapping with JPA Annotations”?

Define @Entity, @Table, @Id, @GeneratedValue, @Column, and @Embedded for clean entity design. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Java Academy?

No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Entity Mapping with JPA Annotations” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Java Academy lesson?

Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Entity Mapping with JPA Annotations
  2. Spring Data Repositories and Query Methods
  3. One-to-Many and Many-to-Many Relationships
  4. Pagination, Sorting, and Projections
← Back to Java Academy