CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-jakarta-persistence--jakarta-persistence-api

Jakarta Persistence API provides a comprehensive framework for object-relational mapping, entity lifecycle management, and database operations in Java applications

Overview
Eval results
Files

entity-mapping.mddocs/

Entity Mapping and Relationships

Complete reference for entity annotations, relationship mappings, inheritance strategies, and mapping customizations in Jakarta Persistence.

Imports

import jakarta.persistence.*;

Capabilities

Entity Definition

Define entities that map Java classes to database tables.

/**
 * Specifies that the class is an entity
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface Entity {
    /**
     * (Optional) The entity name. Defaults to the unqualified name of the entity class.
     * This name is used to refer to the entity in queries.
     */
    String name() default "";
}

/**
 * Specifies the primary table for the annotated entity
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
    /** (Optional) The name of the table */
    String name() default "";

    /** (Optional) The catalog of the table */
    String catalog() default "";

    /** (Optional) The schema of the table */
    String schema() default "";

    /** (Optional) Unique constraints to be placed on the table */
    UniqueConstraint[] uniqueConstraints() default {};

    /** (Optional) Indexes for the table */
    Index[] indexes() default {};
}

/**
 * Designates a class whose mapping information is applied to entities that inherit from it
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface MappedSuperclass {
}

/**
 * Specifies that a class whose instances are stored as an intrinsic part of an owning entity
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface Embeddable {
}

/**
 * Specifies that the property or field is not persistent
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Transient {
}

Usage Example:

@Entity
@Table(name = "customers", schema = "sales")
public class Customer {
    @Id
    private Long id;
    private String name;
}

@MappedSuperclass
public abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Version
    private Integer version;
}

@Embeddable
public class Address {
    private String street;
    private String city;
    private String zipCode;
}

Primary Keys

Define primary key fields and generation strategies.

/**
 * Specifies the primary key of an entity
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Id {
}

/**
 * Provides for the specification of generation strategies for primary keys
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
    /** (Optional) The primary key generation strategy */
    GenerationType strategy() default GenerationType.AUTO;

    /** (Optional) The name of the primary key generator */
    String generator() default "";
}

/**
 * Specifies a composite primary key class
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface IdClass {
    /** The primary key class */
    Class value();
}

/**
 * Applied to a persistent field or property to denote a composite primary key
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface EmbeddedId {
}

/**
 * Defines a primary key generator that may be referenced by name
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator {
    /** (Required) A unique generator name */
    String name();

    /** (Optional) The name of the database sequence object */
    String sequenceName() default "";

    /** (Optional) The catalog of the sequence generator */
    String catalog() default "";

    /** (Optional) The schema of the sequence generator */
    String schema() default "";

    /** (Optional) The value from which the sequence object is to start */
    int initialValue() default 1;

    /** (Optional) The amount to increment by when allocating sequence numbers */
    int allocationSize() default 50;
}

/**
 * Used to group SequenceGenerator annotations
 * @since 2.2
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface SequenceGenerators {
    /** Array of sequence generators */
    SequenceGenerator[] value();
}

/**
 * Defines a primary key generator using a database table
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface TableGenerator {
    /** (Required) A unique generator name */
    String name();

    /** (Optional) Name of table that stores the generated id values */
    String table() default "";

    /** (Optional) The catalog of the table */
    String catalog() default "";

    /** (Optional) The schema of the table */
    String schema() default "";

    /** (Optional) Name of the primary key column in the table */
    String pkColumnName() default "";

    /** (Optional) Name of the column that stores the generated id value */
    String valueColumnName() default "";

    /** (Optional) The primary key value in the generator table */
    String pkColumnValue() default "";

    /** (Optional) The initial value to be used */
    int initialValue() default 0;

    /** (Optional) The amount to increment by */
    int allocationSize() default 50;

    /** (Optional) Unique constraints on the table */
    UniqueConstraint[] uniqueConstraints() default {};

    /** (Optional) Indexes for the table */
    Index[] indexes() default {};
}

/**
 * Used to group TableGenerator annotations
 * @since 2.2
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface TableGenerators {
    /** Array of table generators */
    TableGenerator[] value();
}

Usage Example:

// Simple primary key
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

// Sequence generator
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq")
    @SequenceGenerator(name = "order_seq", sequenceName = "order_sequence", allocationSize = 10)
    private Long id;
}

// Composite key with @IdClass
@Entity
@IdClass(OrderItemId.class)
public class OrderItem {
    @Id
    private Long orderId;

    @Id
    private Long productId;

    private Integer quantity;
}

// Composite key with @EmbeddedId
@Entity
public class OrderItem {
    @EmbeddedId
    private OrderItemId id;

    private Integer quantity;
}

@Embeddable
public class OrderItemId implements Serializable {
    private Long orderId;
    private Long productId;
}

Column Mapping

Map entity fields to database columns with detailed configuration.

/**
 * Specifies the mapped column for a persistent property or field
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {
    /** (Optional) The name of the column */
    String name() default "";

    /** (Optional) Whether the column is a unique key */
    boolean unique() default false;

    /** (Optional) Whether the database column is nullable */
    boolean nullable() default true;

    /** (Optional) Whether the column is included in SQL INSERT statements */
    boolean insertable() default true;

    /** (Optional) Whether the column is included in SQL UPDATE statements */
    boolean updatable() default true;

    /** (Optional) The SQL fragment to use when generating the DDL */
    String columnDefinition() default "";

    /** (Optional) The name of the table containing the column */
    String table() default "";

    /** (Optional) The column length (for String values) */
    int length() default 255;

    /** (Optional) The precision for a decimal column */
    int precision() default 0;

    /** (Optional) The scale for a decimal column */
    int scale() default 0;
}

/**
 * The simplest type of mapping to a database column
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Basic {
    /** (Optional) Whether the value should be lazily fetched */
    FetchType fetch() default FetchType.EAGER;

    /** (Optional) Whether the value may be null */
    boolean optional() default true;
}

/**
 * Specifies that a persistent property or field should be persisted as a large object
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Lob {
}

/**
 * Specifies that a persistent property or field should be persisted as an enumerated type
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Enumerated {
    /** (Optional) The type used in mapping */
    EnumType value() default EnumType.ORDINAL;
}

/**
 * Must be specified for persistent fields or properties of type Date and Calendar
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Temporal {
    /** (Required) The type used in mapping */
    TemporalType value();
}

/**
 * Specifies the version field or property for optimistic locking
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Version {
}

Usage Example:

@Entity
public class Article {
    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "title", nullable = false, length = 200)
    private String title;

    @Lob
    @Column(name = "content")
    private String content;

    @Enumerated(EnumType.STRING)
    @Column(length = 20)
    private ArticleStatus status;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at")
    private Date createdAt;

    @Column(precision = 10, scale = 2)
    private BigDecimal price;

    @Version
    private Integer version;
}

Embedded Objects

Embed objects as part of an entity.

/**
 * Specifies a persistent field or property whose value is an embeddable instance
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Embedded {
}

/**
 * Used to override the mapping of a Basic property or field
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface AttributeOverride {
    /** (Required) The name of the property whose mapping is being overridden */
    String name();

    /** (Required) The column that is being mapped to the persistent attribute */
    Column column();
}

/**
 * Used to override mappings of multiple properties or fields
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface AttributeOverrides {
    /** Array of attribute overrides */
    AttributeOverride[] value();
}

/**
 * Used to override a mapping for an entity relationship
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface AssociationOverride {
    /** (Required) The name of the relationship property whose mapping is being overridden */
    String name();

    /** (Optional) The join columns that are used for the association */
    JoinColumn[] joinColumns() default {};

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);

    /** (Optional) The join table that maps the relationship */
    JoinTable joinTable() default @JoinTable;
}

/**
 * Used to override mappings of multiple relationship properties or fields
 * @since 1.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface AssociationOverrides {
    /** Array of association overrides */
    AssociationOverride[] value();
}

Usage Example:

@Embeddable
public class Address {
    private String street;
    private String city;
    private String zipCode;
}

@Entity
public class Person {
    @Id
    private Long id;

    @Embedded
    private Address homeAddress;

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "street", column = @Column(name = "work_street")),
        @AttributeOverride(name = "city", column = @Column(name = "work_city")),
        @AttributeOverride(name = "zipCode", column = @Column(name = "work_zip"))
    })
    private Address workAddress;
}

Relationships

Define relationships between entities.

/**
 * Specifies a single-valued association to another entity with one-to-one multiplicity
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OneToOne {
    /** (Optional) The entity class that is the target of the association */
    Class targetEntity() default void.class;

    /** (Optional) The operations that must be cascaded to the target */
    CascadeType[] cascade() default {};

    /** (Optional) Whether the association should be lazily loaded or eagerly fetched */
    FetchType fetch() default FetchType.EAGER;

    /** (Optional) Whether the association is optional */
    boolean optional() default true;

    /** (Optional) The field that owns the relationship (bidirectional) */
    String mappedBy() default "";

    /** (Optional) Whether to apply the remove operation to orphaned entities */
    boolean orphanRemoval() default false;
}

/**
 * Specifies a many-valued association with one-to-many multiplicity
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OneToMany {
    /** (Optional) The entity class that is the target of the association */
    Class targetEntity() default void.class;

    /** (Optional) The operations that must be cascaded to the target */
    CascadeType[] cascade() default {};

    /** (Optional) Whether the association should be lazily loaded or eagerly fetched */
    FetchType fetch() default FetchType.LAZY;

    /** (Optional) The field that owns the relationship */
    String mappedBy() default "";

    /** (Optional) Whether to apply the remove operation to orphaned entities */
    boolean orphanRemoval() default false;
}

/**
 * Specifies a single-valued association to another entity with many-to-one multiplicity
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ManyToOne {
    /** (Optional) The entity class that is the target of the association */
    Class targetEntity() default void.class;

    /** (Optional) The operations that must be cascaded to the target */
    CascadeType[] cascade() default {};

    /** (Optional) Whether the association should be lazily loaded or eagerly fetched */
    FetchType fetch() default FetchType.EAGER;

    /** (Optional) Whether the association is optional */
    boolean optional() default true;
}

/**
 * Specifies a many-valued association with many-to-many multiplicity
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ManyToMany {
    /** (Optional) The entity class that is the target of the association */
    Class targetEntity() default void.class;

    /** (Optional) The operations that must be cascaded to the target */
    CascadeType[] cascade() default {};

    /** (Optional) Whether the association should be lazily loaded or eagerly fetched */
    FetchType fetch() default FetchType.LAZY;

    /** (Optional) The field that owns the relationship */
    String mappedBy() default "";
}

/**
 * Specifies a column for joining an entity association
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinColumn {
    /** (Optional) The name of the foreign key column */
    String name() default "";

    /** (Optional) The name of the column referenced by this foreign key column */
    String referencedColumnName() default "";

    /** (Optional) Whether the foreign key column is unique */
    boolean unique() default false;

    /** (Optional) Whether the foreign key column is nullable */
    boolean nullable() default true;

    /** (Optional) Whether the column is included in SQL INSERT statements */
    boolean insertable() default true;

    /** (Optional) Whether the column is included in SQL UPDATE statements */
    boolean updatable() default true;

    /** (Optional) The SQL fragment to use for the column definition */
    String columnDefinition() default "";

    /** (Optional) The name of the table containing the foreign key column */
    String table() default "";

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

/**
 * Specifies the mapping for composite foreign keys
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinColumns {
    /** Array of join columns */
    JoinColumn[] value();

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

/**
 * Specifies the mapping of associations
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinTable {
    /** (Optional) The name of the join table */
    String name() default "";

    /** (Optional) The catalog of the join table */
    String catalog() default "";

    /** (Optional) The schema of the join table */
    String schema() default "";

    /** (Optional) The foreign key columns of the join table */
    JoinColumn[] joinColumns() default {};

    /** (Optional) The foreign key columns of the join table (inverse side) */
    JoinColumn[] inverseJoinColumns() default {};

    /** (Optional) The foreign key constraint for join columns */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);

    /** (Optional) The foreign key constraint for inverse join columns */
    ForeignKey inverseForeignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);

    /** (Optional) Unique constraints on the join table */
    UniqueConstraint[] uniqueConstraints() default {};

    /** (Optional) Indexes for the join table */
    Index[] indexes() default {};
}

/**
 * Designates a ManyToOne or OneToOne relationship attribute for an EmbeddedId primary key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapsId {
    /** (Optional) The name of the attribute within the composite key */
    String value() default "";
}

Usage Example:

// One-to-One
@Entity
public class User {
    @Id
    private Long id;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "profile_id")
    private UserProfile profile;
}

// One-to-Many / Many-to-One (bidirectional)
@Entity
public class Department {
    @Id
    private Long id;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees = new ArrayList<>();
}

@Entity
public class Employee {
    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id", nullable = false)
    private Department department;
}

// Many-to-Many
@Entity
public class Student {
    @Id
    private Long id;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set<Course> courses = new HashSet<>();
}

@Entity
public class Course {
    @Id
    private Long id;

    @ManyToMany(mappedBy = "courses")
    private Set<Student> students = new HashSet<>();
}

Collection Mappings

Map collections of basic types and embeddables.

/**
 * Specifies a collection of instances of a basic type or embeddable class
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ElementCollection {
    /** (Optional) The basic or embeddable class that is the element type of the collection */
    Class targetClass() default void.class;

    /** (Optional) Whether the association should be lazily loaded or eagerly fetched */
    FetchType fetch() default FetchType.LAZY;
}

/**
 * Specifies the table that is used for the mapping of collections
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface CollectionTable {
    /** (Optional) The name of the collection table */
    String name() default "";

    /** (Optional) The catalog of the table */
    String catalog() default "";

    /** (Optional) The schema of the table */
    String schema() default "";

    /** (Optional) The foreign key columns of the collection table */
    JoinColumn[] joinColumns() default {};

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);

    /** (Optional) Unique constraints on the table */
    UniqueConstraint[] uniqueConstraints() default {};

    /** (Optional) Indexes for the table */
    Index[] indexes() default {};
}

/**
 * Specifies the ordering of collection elements
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OrderBy {
    /** (Optional) The ordering clause */
    String value() default "";
}

/**
 * Specifies a column that is used to maintain the persistent order of a list
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OrderColumn {
    /** (Optional) The name of the ordering column */
    String name() default "";

    /** (Optional) Whether the column is nullable */
    boolean nullable() default true;

    /** (Optional) Whether the column is included in SQL INSERT statements */
    boolean insertable() default true;

    /** (Optional) Whether the column is included in SQL UPDATE statements */
    boolean updatable() default true;

    /** (Optional) The SQL fragment for column definition */
    String columnDefinition() default "";
}

Usage Example:

@Entity
public class Person {
    @Id
    private Long id;

    @ElementCollection
    @CollectionTable(name = "phone_numbers", joinColumns = @JoinColumn(name = "person_id"))
    @Column(name = "phone_number")
    private Set<String> phoneNumbers = new HashSet<>();

    @ElementCollection
    @CollectionTable(name = "addresses")
    @OrderColumn(name = "address_index")
    private List<Address> addresses = new ArrayList<>();
}

Map Collections

Map collections with custom keys.

/**
 * Specifies the map key for associations of type Map
 * @since 1.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKey {
    /** (Optional) The name of the persistent field or property of the map key */
    String name() default "";
}

/**
 * Specifies the type of the map key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyClass {
    /** The type of the map key */
    Class value();
}

/**
 * Specifies the mapped column for the map key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyColumn {
    /** (Optional) The name of the map key column */
    String name() default "";

    /** (Optional) Whether the column is unique */
    boolean unique() default false;

    /** (Optional) Whether the column is nullable */
    boolean nullable() default false;

    /** (Optional) Whether the column is insertable */
    boolean insertable() default true;

    /** (Optional) Whether the column is updatable */
    boolean updatable() default true;

    /** (Optional) The SQL fragment for column definition */
    String columnDefinition() default "";

    /** (Optional) The name of the table containing the column */
    String table() default "";

    /** (Optional) The column length */
    int length() default 255;

    /** (Optional) The precision for numeric columns */
    int precision() default 0;

    /** (Optional) The scale for numeric columns */
    int scale() default 0;
}

/**
 * Specifies the enum type for a map key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyEnumerated {
    /** (Optional) The type used in mapping the map key enum */
    EnumType value() default EnumType.ORDINAL;
}

/**
 * Specifies the temporal type for a map key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyTemporal {
    /** (Required) The temporal type for the map key */
    TemporalType value();
}

/**
 * Specifies a mapping to an entity that is a map key
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyJoinColumn {
    /** (Optional) The name of the foreign key column for the map key */
    String name() default "";

    /** (Optional) The name of the column referenced by this foreign key column */
    String referencedColumnName() default "";

    /** (Optional) Whether the column is unique */
    boolean unique() default false;

    /** (Optional) Whether the column is nullable */
    boolean nullable() default false;

    /** (Optional) Whether the column is insertable */
    boolean insertable() default true;

    /** (Optional) Whether the column is updatable */
    boolean updatable() default true;

    /** (Optional) The SQL fragment for column definition */
    String columnDefinition() default "";

    /** (Optional) The name of the table containing the column */
    String table() default "";

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

/**
 * Specifies the mapping for composite map key join columns
 * @since 2.0
 */
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKeyJoinColumns {
    /** Array of map key join columns */
    MapKeyJoinColumn[] value();

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

Usage Example:

@Entity
public class Company {
    @Id
    private Long id;

    @OneToMany
    @MapKey(name = "employeeId")
    private Map<String, Employee> employeesByNumber = new HashMap<>();

    @ElementCollection
    @MapKeyColumn(name = "department_name")
    @Column(name = "budget")
    private Map<String, BigDecimal> departmentBudgets = new HashMap<>();
}

Inheritance Mapping

Map entity inheritance hierarchies to database tables.

/**
 * Specifies the inheritance strategy for an entity class hierarchy
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface Inheritance {
    /** (Optional) The strategy to use */
    InheritanceType strategy() default InheritanceType.SINGLE_TABLE;
}

/**
 * Specifies the discriminator column for SINGLE_TABLE and JOINED inheritance
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface DiscriminatorColumn {
    /** (Optional) The name of the discriminator column */
    String name() default "DTYPE";

    /** (Optional) The type of object used to represent the discriminator column */
    DiscriminatorType discriminatorType() default DiscriminatorType.STRING;

    /** (Optional) The SQL fragment for column definition */
    String columnDefinition() default "";

    /** (Optional) The column length for STRING discriminator types */
    int length() default 31;
}

/**
 * Specifies the value of the discriminator column for entities of the given type
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface DiscriminatorValue {
    /** (Required) The discriminator value */
    String value();
}

/**
 * Specifies a primary key column used as a foreign key to join to another table
 * @since 1.0
 */
@Target({METHOD, FIELD, TYPE})
@Retention(RUNTIME)
public @interface PrimaryKeyJoinColumn {
    /** (Optional) The name of the primary key column */
    String name() default "";

    /** (Optional) The name of the primary key column of the referenced table */
    String referencedColumnName() default "";

    /** (Optional) The SQL fragment for column definition */
    String columnDefinition() default "";

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

/**
 * Groups PrimaryKeyJoinColumn annotations for composite foreign keys
 * @since 1.0
 */
@Target({TYPE})
@Retention(RUNTIME)
public @interface PrimaryKeyJoinColumns {
    /** Array of primary key join columns */
    PrimaryKeyJoinColumn[] value();

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
}

Usage Example:

// Single table inheritance
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
    @Id
    private Long id;
    private String manufacturer;
}

@Entity
@DiscriminatorValue("CAR")
public class Car extends Vehicle {
    private Integer numberOfDoors;
}

@Entity
@DiscriminatorValue("TRUCK")
public class Truck extends Vehicle {
    private BigDecimal payloadCapacity;
}

// Joined table inheritance
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Account {
    @Id
    private Long id;
    private String accountNumber;
}

@Entity
@PrimaryKeyJoinColumn(name = "account_id")
public class SavingsAccount extends Account {
    private BigDecimal interestRate;
}

@Entity
@PrimaryKeyJoinColumn(name = "account_id")
public class CheckingAccount extends Account {
    private BigDecimal overdraftLimit;
}

Secondary Tables

Map a single entity to multiple tables.

/**
 * Specifies a secondary table for the annotated entity class
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface SecondaryTable {
    /** (Required) The name of the secondary table */
    String name();

    /** (Optional) The catalog of the table */
    String catalog() default "";

    /** (Optional) The schema of the table */
    String schema() default "";

    /** (Optional) The columns that are used to join with the primary table */
    PrimaryKeyJoinColumn[] pkJoinColumns() default {};

    /** (Optional) The foreign key constraint specification */
    ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);

    /** (Optional) Unique constraints on the table */
    UniqueConstraint[] uniqueConstraints() default {};

    /** (Optional) Indexes for the table */
    Index[] indexes() default {};
}

/**
 * Specifies multiple secondary tables for an entity
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface SecondaryTables {
    /** Array of secondary tables */
    SecondaryTable[] value();
}

Usage Example:

@Entity
@Table(name = "employee")
@SecondaryTable(name = "employee_details",
    pkJoinColumns = @PrimaryKeyJoinColumn(name = "employee_id"))
public class Employee {
    @Id
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(table = "employee_details")
    private String biography;

    @Column(table = "employee_details")
    private byte[] photo;
}

Constraints and Indexes

Define database constraints and indexes.

/**
 * Specifies that a unique constraint is to be included in the generated DDL
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface UniqueConstraint {
    /** (Optional) Constraint name */
    String name() default "";

    /** (Required) An array of column names that make up the constraint */
    String[] columnNames();
}

/**
 * Used in schema generation to specify creation of an index
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface Index {
    /** (Optional) The name of the index */
    String name() default "";

    /** (Required) The list of columns for the index */
    String columnList();

    /** (Optional) Whether the index is unique */
    boolean unique() default false;
}

/**
 * Used to specify the handling of foreign key constraints
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface ForeignKey {
    /** (Optional) The name of the foreign key constraint */
    String name() default "";

    /** (Optional) The constraint mode */
    ConstraintMode value() default ConstraintMode.PROVIDER_DEFAULT;

    /** (Optional) The foreign key constraint definition */
    String foreignKeyDefinition() default "";
}

Access Type

Specify field or property access for entities.

/**
 * Used to specify an access type for an entity class, mapped superclass, or embeddable class
 * @since 2.0
 */
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Access {
    /** (Required) The access type */
    AccessType value();
}

Usage Example:

@Entity
@Access(AccessType.FIELD)
public class Product {
    @Id
    private Long id;

    private String name;

    @Access(AccessType.PROPERTY)
    @Column(name = "price")
    public BigDecimal getPrice() {
        return price.setScale(2, RoundingMode.HALF_UP);
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    private BigDecimal price;
}

Attribute Converters

Convert entity attribute values to database column values.

/**
 * Specifies the conversion of a Basic field or property
 * @since 2.1
 */
@Target({METHOD, FIELD, TYPE})
@Retention(RUNTIME)
@Repeatable(Converts.class)
public @interface Convert {
    /** (Optional) The converter class */
    Class converter() default void.class;

    /** (Optional) The name of the attribute to which the converter is applied */
    String attributeName() default "";

    /** (Optional) Whether to disable conversion */
    boolean disableConversion() default false;
}

/**
 * Used to group Convert annotations
 * @since 2.1
 */
@Target({METHOD, FIELD, TYPE})
@Retention(RUNTIME)
public @interface Converts {
    /** Array of converts */
    Convert[] value();
}

/**
 * Specifies that the annotated class is a converter
 * @since 2.1
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface Converter {
    /** (Optional) Whether the converter should be auto-applied */
    boolean autoApply() default false;
}

/**
 * Interface for entity attribute value conversion
 * @since 2.1
 */
public interface AttributeConverter<X, Y> {
    /**
     * Converts the entity attribute value to database column value
     * @param attribute the entity attribute value
     * @return the database column value
     */
    Y convertToDatabaseColumn(X attribute);

    /**
     * Converts the database column value to entity attribute value
     * @param dbData the database column value
     * @return the entity attribute value
     */
    X convertToEntityAttribute(Y dbData);
}

Usage Example:

@Converter(autoApply = true)
public class BooleanToYNConverter implements AttributeConverter<Boolean, String> {
    @Override
    public String convertToDatabaseColumn(Boolean attribute) {
        return attribute != null && attribute ? "Y" : "N";
    }

    @Override
    public Boolean convertToEntityAttribute(String dbData) {
        return "Y".equals(dbData);
    }
}

@Entity
public class Customer {
    @Id
    private Long id;

    @Convert(converter = BooleanToYNConverter.class)
    private Boolean active;
}

Entity Graphs

Define named entity graphs for optimizing fetch strategies and controlling which associations should be loaded.

/**
 * Used to specify the path and boundaries for a find operation or query
 * @since 2.1
 */
@Repeatable(NamedEntityGraphs.class)
@Target(TYPE)
@Retention(RUNTIME)
public @interface NamedEntityGraph {
    /**
     * (Optional) The name of the entity graph. Defaults to the entity name of the root entity
     */
    String name() default "";

    /**
     * A list of attributes of the entity that are included in this graph
     */
    NamedAttributeNode[] attributeNodes() default {};

    /**
     * Include all of the attributes of the annotated entity class as attribute nodes
     */
    boolean includeAllAttributes() default false;

    /**
     * A list of subgraphs that are included in the entity graph
     */
    NamedSubgraph[] subgraphs() default {};

    /**
     * A list of subgraphs that will add additional attributes for subclasses
     */
    NamedSubgraph[] subclassSubgraphs() default {};
}

/**
 * Used to group NamedEntityGraph annotations
 * @since 2.1
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface NamedEntityGraphs {
    /** Array of NamedEntityGraph annotations */
    NamedEntityGraph[] value();
}

/**
 * A member element of a NamedEntityGraph
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface NamedAttributeNode {
    /**
     * The name of the attribute that must be included in the graph
     */
    String value();

    /**
     * If the attribute references a managed type, refer to that NamedSubgraph definition
     */
    String subgraph() default "";

    /**
     * If the attribute references a Map, specify a subgraph for the Entity key type
     */
    String keySubgraph() default "";
}

/**
 * A member element of a NamedEntityGraph, referenced from NamedAttributeNode
 * @since 2.1
 */
@Target({})
@Retention(RUNTIME)
public @interface NamedSubgraph {
    /**
     * The name of the subgraph as referenced from a NamedAttributeNode element
     */
    String name();

    /**
     * The type represented by this subgraph
     */
    Class type() default void.class;

    /**
     * The list of attributes of the class that must be included
     */
    NamedAttributeNode[] attributeNodes();
}

Usage Example:

@Entity
@NamedEntityGraph(
    name = "Order.detail",
    attributeNodes = {
        @NamedAttributeNode("customer"),
        @NamedAttributeNode(value = "items", subgraph = "items.detail")
    },
    subgraphs = {
        @NamedSubgraph(
            name = "items.detail",
            attributeNodes = {
                @NamedAttributeNode("product"),
                @NamedAttributeNode("quantity")
            }
        )
    }
)
public class Order {
    @Id
    private Long id;

    @ManyToOne
    private Customer customer;

    @OneToMany
    private List<OrderItem> items;
}

// Use the entity graph
EntityGraph<?> graph = em.getEntityGraph("Order.detail");
Map<String, Object> props = new HashMap<>();
props.put("jakarta.persistence.fetchgraph", graph);
Order order = em.find(Order.class, orderId, props);

Container and CDI Injection

Annotations for dependency injection of persistence contexts and entity manager factories in Jakarta EE containers.

/**
 * Expresses a dependency on a container-managed EntityManager
 * @since 1.0
 */
@Repeatable(PersistenceContexts.class)
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface PersistenceContext {
    /**
     * (Optional) The name by which the entity manager is to be accessed
     */
    String name() default "";

    /**
     * (Optional) The name of the persistence unit as defined in persistence.xml
     */
    String unitName() default "";

    /**
     * (Optional) Specifies whether a transaction-scoped or extended persistence context is used
     */
    PersistenceContextType type() default PersistenceContextType.TRANSACTION;

    /**
     * (Optional) Specifies whether the persistence context is automatically synchronized
     * @since 2.1
     */
    SynchronizationType synchronization() default SynchronizationType.SYNCHRONIZED;

    /**
     * (Optional) Properties for the container or persistence provider
     */
    PersistenceProperty[] properties() default {};
}

/**
 * Declares one or more PersistenceContext annotations
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface PersistenceContexts {
    /** One or more PersistenceContext annotations */
    PersistenceContext[] value();
}

/**
 * Expresses a dependency on an EntityManagerFactory
 * @since 1.0
 */
@Repeatable(PersistenceUnits.class)
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface PersistenceUnit {
    /**
     * (Optional) The name by which the entity manager factory is to be accessed
     */
    String name() default "";

    /**
     * (Optional) The name of the persistence unit as defined in persistence.xml
     */
    String unitName() default "";
}

/**
 * Declares one or more PersistenceUnit annotations
 * @since 1.0
 */
@Target(TYPE)
@Retention(RUNTIME)
public @interface PersistenceUnits {
    /** One or more PersistenceUnit annotations */
    PersistenceUnit[] value();
}

/**
 * Describes a single container or persistence provider property
 * @since 1.0
 */
@Target({})
@Retention(RUNTIME)
public @interface PersistenceProperty {
    /** The name of the property */
    String name();

    /** The value of the property */
    String value();
}

Usage Example:

@Stateless
public class OrderService {
    // Inject EntityManager
    @PersistenceContext(unitName = "orderDB")
    private EntityManager em;

    // Inject EntityManagerFactory
    @PersistenceUnit(unitName = "orderDB")
    private EntityManagerFactory emf;

    // With properties
    @PersistenceContext(
        unitName = "orderDB",
        type = PersistenceContextType.EXTENDED,
        properties = {
            @PersistenceProperty(name = "jakarta.persistence.cache.storeMode", value = "REFRESH")
        }
    )
    private EntityManager extendedEm;

    public void processOrder(Long orderId) {
        Order order = em.find(Order.class, orderId);
        // Process order
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-jakarta-persistence--jakarta-persistence-api

docs

caching-locking.md

criteria-api.md

entity-manager.md

entity-mapping.md

index.md

lifecycle-callbacks.md

metamodel.md

queries.md

spi.md

tile.json