02 JPA Basics
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
publicorprotectedconstructor (additional constructors are allowed). - not be
final,interface,recordorenum. - 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.