The Jakarta Persistence API (JPA) is a Java specification for accessing, persisting, and managing data between Java objects and a relational database. It is part of the Jakarta EE platform and is used to define a standard way to map Java objects to relational database tables and vice versa.

Movie Rental Application

The movie rental application is the sample application used in this course.

Data Model

classDiagram
    User "1" <--> "0..*" Rental
    Rental "1" --> "1" Movie
    Movie "0..*" --> "1" PriceCategory
    Regular --|> PriceCategory
    Children --|> PriceCategory
    New Release --|> PriceCategory

Component Wiring

  • Service Layer: Core API through which other layers will interface (facade pattern). Define the business logic.
  • Repository Layer: Data access layer. Define the data access logic. Responsible for CRUD operations.
block-beta
columns 1
    block:Controllers
        UserController
        RentalController
        MovieController
        PriceCategoryController
    end
    space
    block:Services
        UserService
        RentalService
        MovieService
        PriceCategoryService
    end
    space
    block:Repositories
        UserRepository
        RentalRepository
        MovieRepository
        PriceCategoryRepository
    end
    space
    UserController --> UserService
    RentalController --> UserService
    RentalController --> RentalService
    RentalController --> MovieService
    MovieController --> MovieService
    PriceCategoryController --> MovieService
    UserService --> UserRepository
    UserService --> RentalRepository
    UserService --> MovieRepository
    RentalService --> RentalRepository
    MovieService --> MovieRepository
    MovieService --> PriceCategoryRepository
    UserRepository --> RentalRepository
    RentalRepository --> UserRepository
    RentalRepository --> MovieRepository
    MovieRepository --> PriceCategoryRepository

Features

JPA allows developers to:

  • perform operations on Java objects without having to write SQL queries.
  • persist changes to the database automatically (persistance conntext).
  • define relationships between Java objects and support polymorphic queries.

Annotations

JPA uses annotations to configure the mapping between Java objects and database tables. To be recognized as an entity class, a Java class must:

  • be annotated with @Entity.
  • have a parameterless public or protected constructor (additional constructors are allowed).
  • not be final, interface, record or enum.
  • contain non-final instance fields for persistance.

Supported Types

JPA supports the following types:

  • Primitive types (int, long, double, etc.).
  • Serializable types (Strings, Primitive Wrappers, Date, etc.).
  • User-defined serializable types.
  • Enums.
  • Entity types and collections of entity types.

Annotations

  • @Entity: Specifies that the class is an entity.
    • name: Specifies the entity name.
  • @Table: Specifies the table name for the entity.
    • name: Specifies the table name.
    • schema: Specifies the schema name.
    • catalog: Specifies the catalog name.
    • uniqueConstraints: Specifies unique constraints.
  • @Column: Specifies the column name for a field.
    • name: Specifies the column name.
    • nullable: Specifies if the column is nullable.
    • unique: Specifies if the column is unique.
    • length: Specifies the column length.
    • precision: Specifies the column precision.
    • scale: Specifies the column scale.
    • insertable: If SQL insert is allowed.
    • updatable: If SQL update is allowed.
  • @Id: Specifies the primary key of an entity. Must be numeric primitive type.
  • @Enumerated: Specifies the enum type.
    • EnumType.ORDINAL: Stores the enum as integer.
    • EnumType.STRING: Stores the enum as string.
  • @GeneratedValue: Specifies the generation strategy for the primary key.
    • strategy: Specifies the generation strategy.
      • GenerationType.AUTO: Default strategy.
      • GenerationType.IDENTITY: Database identity column.
      • GenerationType.SEQUENCE: Database sequence.
      • GenerationType.TABLE: Database table.
    • generator: Specifies the sequence or table generator name.

Associations

  • @OneToOne: Specifies a one-to-one relationship.
    • mappedBy: Specifies the field that owns the relationship.
    • cascade: Specifies the operations to cascade.
  • @OneToMany: Specifies a one-to-many relationship.
    • mappedBy: Specifies the field that owns the relationship.
    • cascade: Specifies the operations to cascade.
  • @ManyToOne: Specifies a many-to-one relationship.
    • cascade: Specifies the operations to cascade.
  • @ManyToMany: Specifies a many-to-many relationship.
    • mappedBy: Specifies the field that owns the relationship.
    • cascade: Specifies the operations to cascade.
  • @JoinColumn: Specifies the join column for an association.
    • name: Specifies the column name.
    • referencedColumnName: Specifies the referenced column name.
    • nullable: Specifies if the column is nullable.
    • unique: Specifies if the column is unique.
    • insertable: If SQL insert is allowed.
    • updatable: If SQL update is allowed.

Associations can be unidirectional or bidirectional. For bidirectional associations, one side is marked with mappedBy (called the inverse side), the other side is called the owning side.

Inheritance

Inheritance is not known to the database, so JPA provides strategies to map inheritance hierarchies to the database.

Entity Manager

The EntityManager is the primary interface used to interact with the persistence context. It is used to perform operations on entities such as persist, merge, remove, and find.

Persistence Context

The persistence context is a set of managed entities that are associated with the current transaction. The persistence context is created when the EntityManager is created and is closed when the transaction is committed or rolled back.

Entity instances are in one of the following states:

  • Managed: The entity is managed by the EntityManager.
  • Detached: The entity was managed but is no longer associated with the EntityManager.
  • Removed: The entity is marked for removal.
  • Transient: The entity is not associated with the EntityManager.
stateDiagram-v2
    n: New
    m: Managed
    d: Detached
    r: Removed
    db: Database

    n --> m: persist(e) / merge(e)
    m --> m: refresh(e)
    m --> d: detach(e) / clear() / close()
    d --> m: merge(e)
    m --> r: remove(e)
    r --> m: persist(e)
    r --> db: flush()
    m --> db: flush()
    db --> m: find(...) / createQuery().getResultList() / createQuery().getSingleResult()

Interface

The EntityManager interface provides methods to interact with the persistence context:

  • persist(Object entity): Adds an entity to the persistence context (create).
  • merge(T entity): Updates an entity in the persistence context (update).
  • remove(Object entity): Removes an entity from the persistence context (delete).
  • find(Class<T> entityClass, Object primaryKey): Finds an entity by its primary key.
  • flush(): Synchronizes the persistence context with the database.
  • setFlushMode(FlushModeType flushMode): Sets the flush mode.
  • getFlushMode(): Gets the flush mode.
  • refresh(Object entity): Refreshes the entity state from the database.
  • clear(): Clears the persistence context (detach all entities).
  • contains(Object entity): Checks if an entity is managed.
  • detach(Object entity): Detaches an entity from the persistence context.
  • createQuery(String qlString): Creates a query object.
  • createNamedQuery(String name): Creates a named query object.

Transactions

The entity manager requires a transaction to be active to perform operations. The transaction is started and committed by the EntityManager. A transaction can be started using the @Transactional annotation.

Configuration

JPA can be configured using the applicatin.properties file. A complete list of the available properties can be found under in the Spring documentation.

Common Application Properties