0
# Entity Mapping and Relationships
1
2
Complete reference for entity annotations, relationship mappings, inheritance strategies, and mapping customizations in Jakarta Persistence.
3
4
## Imports
5
6
```java { .api }
7
import jakarta.persistence.*;
8
```
9
10
## Capabilities
11
12
### Entity Definition
13
14
Define entities that map Java classes to database tables.
15
16
```java { .api }
17
/**
18
* Specifies that the class is an entity
19
* @since 1.0
20
*/
21
@Target(TYPE)
22
@Retention(RUNTIME)
23
public @interface Entity {
24
/**
25
* (Optional) The entity name. Defaults to the unqualified name of the entity class.
26
* This name is used to refer to the entity in queries.
27
*/
28
String name() default "";
29
}
30
31
/**
32
* Specifies the primary table for the annotated entity
33
* @since 1.0
34
*/
35
@Target(TYPE)
36
@Retention(RUNTIME)
37
public @interface Table {
38
/** (Optional) The name of the table */
39
String name() default "";
40
41
/** (Optional) The catalog of the table */
42
String catalog() default "";
43
44
/** (Optional) The schema of the table */
45
String schema() default "";
46
47
/** (Optional) Unique constraints to be placed on the table */
48
UniqueConstraint[] uniqueConstraints() default {};
49
50
/** (Optional) Indexes for the table */
51
Index[] indexes() default {};
52
}
53
54
/**
55
* Designates a class whose mapping information is applied to entities that inherit from it
56
* @since 1.0
57
*/
58
@Target(TYPE)
59
@Retention(RUNTIME)
60
public @interface MappedSuperclass {
61
}
62
63
/**
64
* Specifies that a class whose instances are stored as an intrinsic part of an owning entity
65
* @since 1.0
66
*/
67
@Target(TYPE)
68
@Retention(RUNTIME)
69
public @interface Embeddable {
70
}
71
72
/**
73
* Specifies that the property or field is not persistent
74
* @since 1.0
75
*/
76
@Target({METHOD, FIELD})
77
@Retention(RUNTIME)
78
public @interface Transient {
79
}
80
```
81
82
**Usage Example:**
83
84
```java
85
@Entity
86
@Table(name = "customers", schema = "sales")
87
public class Customer {
88
@Id
89
private Long id;
90
private String name;
91
}
92
93
@MappedSuperclass
94
public abstract class BaseEntity {
95
@Id
96
@GeneratedValue(strategy = GenerationType.IDENTITY)
97
private Long id;
98
99
@Version
100
private Integer version;
101
}
102
103
@Embeddable
104
public class Address {
105
private String street;
106
private String city;
107
private String zipCode;
108
}
109
```
110
111
### Primary Keys
112
113
Define primary key fields and generation strategies.
114
115
```java { .api }
116
/**
117
* Specifies the primary key of an entity
118
* @since 1.0
119
*/
120
@Target({METHOD, FIELD})
121
@Retention(RUNTIME)
122
public @interface Id {
123
}
124
125
/**
126
* Provides for the specification of generation strategies for primary keys
127
* @since 1.0
128
*/
129
@Target({METHOD, FIELD})
130
@Retention(RUNTIME)
131
public @interface GeneratedValue {
132
/** (Optional) The primary key generation strategy */
133
GenerationType strategy() default GenerationType.AUTO;
134
135
/** (Optional) The name of the primary key generator */
136
String generator() default "";
137
}
138
139
/**
140
* Specifies a composite primary key class
141
* @since 1.0
142
*/
143
@Target(TYPE)
144
@Retention(RUNTIME)
145
public @interface IdClass {
146
/** The primary key class */
147
Class value();
148
}
149
150
/**
151
* Applied to a persistent field or property to denote a composite primary key
152
* @since 1.0
153
*/
154
@Target({METHOD, FIELD})
155
@Retention(RUNTIME)
156
public @interface EmbeddedId {
157
}
158
159
/**
160
* Defines a primary key generator that may be referenced by name
161
* @since 1.0
162
*/
163
@Target({TYPE, METHOD, FIELD})
164
@Retention(RUNTIME)
165
public @interface SequenceGenerator {
166
/** (Required) A unique generator name */
167
String name();
168
169
/** (Optional) The name of the database sequence object */
170
String sequenceName() default "";
171
172
/** (Optional) The catalog of the sequence generator */
173
String catalog() default "";
174
175
/** (Optional) The schema of the sequence generator */
176
String schema() default "";
177
178
/** (Optional) The value from which the sequence object is to start */
179
int initialValue() default 1;
180
181
/** (Optional) The amount to increment by when allocating sequence numbers */
182
int allocationSize() default 50;
183
}
184
185
/**
186
* Used to group SequenceGenerator annotations
187
* @since 2.2
188
*/
189
@Target({TYPE})
190
@Retention(RUNTIME)
191
public @interface SequenceGenerators {
192
/** Array of sequence generators */
193
SequenceGenerator[] value();
194
}
195
196
/**
197
* Defines a primary key generator using a database table
198
* @since 1.0
199
*/
200
@Target({TYPE, METHOD, FIELD})
201
@Retention(RUNTIME)
202
public @interface TableGenerator {
203
/** (Required) A unique generator name */
204
String name();
205
206
/** (Optional) Name of table that stores the generated id values */
207
String table() default "";
208
209
/** (Optional) The catalog of the table */
210
String catalog() default "";
211
212
/** (Optional) The schema of the table */
213
String schema() default "";
214
215
/** (Optional) Name of the primary key column in the table */
216
String pkColumnName() default "";
217
218
/** (Optional) Name of the column that stores the generated id value */
219
String valueColumnName() default "";
220
221
/** (Optional) The primary key value in the generator table */
222
String pkColumnValue() default "";
223
224
/** (Optional) The initial value to be used */
225
int initialValue() default 0;
226
227
/** (Optional) The amount to increment by */
228
int allocationSize() default 50;
229
230
/** (Optional) Unique constraints on the table */
231
UniqueConstraint[] uniqueConstraints() default {};
232
233
/** (Optional) Indexes for the table */
234
Index[] indexes() default {};
235
}
236
237
/**
238
* Used to group TableGenerator annotations
239
* @since 2.2
240
*/
241
@Target({TYPE})
242
@Retention(RUNTIME)
243
public @interface TableGenerators {
244
/** Array of table generators */
245
TableGenerator[] value();
246
}
247
```
248
249
**Usage Example:**
250
251
```java
252
// Simple primary key
253
@Entity
254
public class Product {
255
@Id
256
@GeneratedValue(strategy = GenerationType.IDENTITY)
257
private Long id;
258
}
259
260
// Sequence generator
261
@Entity
262
public class Order {
263
@Id
264
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq")
265
@SequenceGenerator(name = "order_seq", sequenceName = "order_sequence", allocationSize = 10)
266
private Long id;
267
}
268
269
// Composite key with @IdClass
270
@Entity
271
@IdClass(OrderItemId.class)
272
public class OrderItem {
273
@Id
274
private Long orderId;
275
276
@Id
277
private Long productId;
278
279
private Integer quantity;
280
}
281
282
// Composite key with @EmbeddedId
283
@Entity
284
public class OrderItem {
285
@EmbeddedId
286
private OrderItemId id;
287
288
private Integer quantity;
289
}
290
291
@Embeddable
292
public class OrderItemId implements Serializable {
293
private Long orderId;
294
private Long productId;
295
}
296
```
297
298
### Column Mapping
299
300
Map entity fields to database columns with detailed configuration.
301
302
```java { .api }
303
/**
304
* Specifies the mapped column for a persistent property or field
305
* @since 1.0
306
*/
307
@Target({METHOD, FIELD})
308
@Retention(RUNTIME)
309
public @interface Column {
310
/** (Optional) The name of the column */
311
String name() default "";
312
313
/** (Optional) Whether the column is a unique key */
314
boolean unique() default false;
315
316
/** (Optional) Whether the database column is nullable */
317
boolean nullable() default true;
318
319
/** (Optional) Whether the column is included in SQL INSERT statements */
320
boolean insertable() default true;
321
322
/** (Optional) Whether the column is included in SQL UPDATE statements */
323
boolean updatable() default true;
324
325
/** (Optional) The SQL fragment to use when generating the DDL */
326
String columnDefinition() default "";
327
328
/** (Optional) The name of the table containing the column */
329
String table() default "";
330
331
/** (Optional) The column length (for String values) */
332
int length() default 255;
333
334
/** (Optional) The precision for a decimal column */
335
int precision() default 0;
336
337
/** (Optional) The scale for a decimal column */
338
int scale() default 0;
339
}
340
341
/**
342
* The simplest type of mapping to a database column
343
* @since 1.0
344
*/
345
@Target({METHOD, FIELD})
346
@Retention(RUNTIME)
347
public @interface Basic {
348
/** (Optional) Whether the value should be lazily fetched */
349
FetchType fetch() default FetchType.EAGER;
350
351
/** (Optional) Whether the value may be null */
352
boolean optional() default true;
353
}
354
355
/**
356
* Specifies that a persistent property or field should be persisted as a large object
357
* @since 1.0
358
*/
359
@Target({METHOD, FIELD})
360
@Retention(RUNTIME)
361
public @interface Lob {
362
}
363
364
/**
365
* Specifies that a persistent property or field should be persisted as an enumerated type
366
* @since 1.0
367
*/
368
@Target({METHOD, FIELD})
369
@Retention(RUNTIME)
370
public @interface Enumerated {
371
/** (Optional) The type used in mapping */
372
EnumType value() default EnumType.ORDINAL;
373
}
374
375
/**
376
* Must be specified for persistent fields or properties of type Date and Calendar
377
* @since 1.0
378
*/
379
@Target({METHOD, FIELD})
380
@Retention(RUNTIME)
381
public @interface Temporal {
382
/** (Required) The type used in mapping */
383
TemporalType value();
384
}
385
386
/**
387
* Specifies the version field or property for optimistic locking
388
* @since 1.0
389
*/
390
@Target({METHOD, FIELD})
391
@Retention(RUNTIME)
392
public @interface Version {
393
}
394
```
395
396
**Usage Example:**
397
398
```java
399
@Entity
400
public class Article {
401
@Id
402
@GeneratedValue
403
private Long id;
404
405
@Column(name = "title", nullable = false, length = 200)
406
private String title;
407
408
@Lob
409
@Column(name = "content")
410
private String content;
411
412
@Enumerated(EnumType.STRING)
413
@Column(length = 20)
414
private ArticleStatus status;
415
416
@Temporal(TemporalType.TIMESTAMP)
417
@Column(name = "created_at")
418
private Date createdAt;
419
420
@Column(precision = 10, scale = 2)
421
private BigDecimal price;
422
423
@Version
424
private Integer version;
425
}
426
```
427
428
### Embedded Objects
429
430
Embed objects as part of an entity.
431
432
```java { .api }
433
/**
434
* Specifies a persistent field or property whose value is an embeddable instance
435
* @since 1.0
436
*/
437
@Target({METHOD, FIELD})
438
@Retention(RUNTIME)
439
public @interface Embedded {
440
}
441
442
/**
443
* Used to override the mapping of a Basic property or field
444
* @since 1.0
445
*/
446
@Target({TYPE, METHOD, FIELD})
447
@Retention(RUNTIME)
448
public @interface AttributeOverride {
449
/** (Required) The name of the property whose mapping is being overridden */
450
String name();
451
452
/** (Required) The column that is being mapped to the persistent attribute */
453
Column column();
454
}
455
456
/**
457
* Used to override mappings of multiple properties or fields
458
* @since 1.0
459
*/
460
@Target({TYPE, METHOD, FIELD})
461
@Retention(RUNTIME)
462
public @interface AttributeOverrides {
463
/** Array of attribute overrides */
464
AttributeOverride[] value();
465
}
466
467
/**
468
* Used to override a mapping for an entity relationship
469
* @since 1.0
470
*/
471
@Target({TYPE, METHOD, FIELD})
472
@Retention(RUNTIME)
473
public @interface AssociationOverride {
474
/** (Required) The name of the relationship property whose mapping is being overridden */
475
String name();
476
477
/** (Optional) The join columns that are used for the association */
478
JoinColumn[] joinColumns() default {};
479
480
/** (Optional) The foreign key constraint specification */
481
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
482
483
/** (Optional) The join table that maps the relationship */
484
JoinTable joinTable() default @JoinTable;
485
}
486
487
/**
488
* Used to override mappings of multiple relationship properties or fields
489
* @since 1.0
490
*/
491
@Target({TYPE, METHOD, FIELD})
492
@Retention(RUNTIME)
493
public @interface AssociationOverrides {
494
/** Array of association overrides */
495
AssociationOverride[] value();
496
}
497
```
498
499
**Usage Example:**
500
501
```java
502
@Embeddable
503
public class Address {
504
private String street;
505
private String city;
506
private String zipCode;
507
}
508
509
@Entity
510
public class Person {
511
@Id
512
private Long id;
513
514
@Embedded
515
private Address homeAddress;
516
517
@Embedded
518
@AttributeOverrides({
519
@AttributeOverride(name = "street", column = @Column(name = "work_street")),
520
@AttributeOverride(name = "city", column = @Column(name = "work_city")),
521
@AttributeOverride(name = "zipCode", column = @Column(name = "work_zip"))
522
})
523
private Address workAddress;
524
}
525
```
526
527
### Relationships
528
529
Define relationships between entities.
530
531
```java { .api }
532
/**
533
* Specifies a single-valued association to another entity with one-to-one multiplicity
534
* @since 1.0
535
*/
536
@Target({METHOD, FIELD})
537
@Retention(RUNTIME)
538
public @interface OneToOne {
539
/** (Optional) The entity class that is the target of the association */
540
Class targetEntity() default void.class;
541
542
/** (Optional) The operations that must be cascaded to the target */
543
CascadeType[] cascade() default {};
544
545
/** (Optional) Whether the association should be lazily loaded or eagerly fetched */
546
FetchType fetch() default FetchType.EAGER;
547
548
/** (Optional) Whether the association is optional */
549
boolean optional() default true;
550
551
/** (Optional) The field that owns the relationship (bidirectional) */
552
String mappedBy() default "";
553
554
/** (Optional) Whether to apply the remove operation to orphaned entities */
555
boolean orphanRemoval() default false;
556
}
557
558
/**
559
* Specifies a many-valued association with one-to-many multiplicity
560
* @since 1.0
561
*/
562
@Target({METHOD, FIELD})
563
@Retention(RUNTIME)
564
public @interface OneToMany {
565
/** (Optional) The entity class that is the target of the association */
566
Class targetEntity() default void.class;
567
568
/** (Optional) The operations that must be cascaded to the target */
569
CascadeType[] cascade() default {};
570
571
/** (Optional) Whether the association should be lazily loaded or eagerly fetched */
572
FetchType fetch() default FetchType.LAZY;
573
574
/** (Optional) The field that owns the relationship */
575
String mappedBy() default "";
576
577
/** (Optional) Whether to apply the remove operation to orphaned entities */
578
boolean orphanRemoval() default false;
579
}
580
581
/**
582
* Specifies a single-valued association to another entity with many-to-one multiplicity
583
* @since 1.0
584
*/
585
@Target({METHOD, FIELD})
586
@Retention(RUNTIME)
587
public @interface ManyToOne {
588
/** (Optional) The entity class that is the target of the association */
589
Class targetEntity() default void.class;
590
591
/** (Optional) The operations that must be cascaded to the target */
592
CascadeType[] cascade() default {};
593
594
/** (Optional) Whether the association should be lazily loaded or eagerly fetched */
595
FetchType fetch() default FetchType.EAGER;
596
597
/** (Optional) Whether the association is optional */
598
boolean optional() default true;
599
}
600
601
/**
602
* Specifies a many-valued association with many-to-many multiplicity
603
* @since 1.0
604
*/
605
@Target({METHOD, FIELD})
606
@Retention(RUNTIME)
607
public @interface ManyToMany {
608
/** (Optional) The entity class that is the target of the association */
609
Class targetEntity() default void.class;
610
611
/** (Optional) The operations that must be cascaded to the target */
612
CascadeType[] cascade() default {};
613
614
/** (Optional) Whether the association should be lazily loaded or eagerly fetched */
615
FetchType fetch() default FetchType.LAZY;
616
617
/** (Optional) The field that owns the relationship */
618
String mappedBy() default "";
619
}
620
621
/**
622
* Specifies a column for joining an entity association
623
* @since 1.0
624
*/
625
@Target({METHOD, FIELD})
626
@Retention(RUNTIME)
627
public @interface JoinColumn {
628
/** (Optional) The name of the foreign key column */
629
String name() default "";
630
631
/** (Optional) The name of the column referenced by this foreign key column */
632
String referencedColumnName() default "";
633
634
/** (Optional) Whether the foreign key column is unique */
635
boolean unique() default false;
636
637
/** (Optional) Whether the foreign key column is nullable */
638
boolean nullable() default true;
639
640
/** (Optional) Whether the column is included in SQL INSERT statements */
641
boolean insertable() default true;
642
643
/** (Optional) Whether the column is included in SQL UPDATE statements */
644
boolean updatable() default true;
645
646
/** (Optional) The SQL fragment to use for the column definition */
647
String columnDefinition() default "";
648
649
/** (Optional) The name of the table containing the foreign key column */
650
String table() default "";
651
652
/** (Optional) The foreign key constraint specification */
653
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
654
}
655
656
/**
657
* Specifies the mapping for composite foreign keys
658
* @since 1.0
659
*/
660
@Target({METHOD, FIELD})
661
@Retention(RUNTIME)
662
public @interface JoinColumns {
663
/** Array of join columns */
664
JoinColumn[] value();
665
666
/** (Optional) The foreign key constraint specification */
667
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
668
}
669
670
/**
671
* Specifies the mapping of associations
672
* @since 1.0
673
*/
674
@Target({METHOD, FIELD})
675
@Retention(RUNTIME)
676
public @interface JoinTable {
677
/** (Optional) The name of the join table */
678
String name() default "";
679
680
/** (Optional) The catalog of the join table */
681
String catalog() default "";
682
683
/** (Optional) The schema of the join table */
684
String schema() default "";
685
686
/** (Optional) The foreign key columns of the join table */
687
JoinColumn[] joinColumns() default {};
688
689
/** (Optional) The foreign key columns of the join table (inverse side) */
690
JoinColumn[] inverseJoinColumns() default {};
691
692
/** (Optional) The foreign key constraint for join columns */
693
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
694
695
/** (Optional) The foreign key constraint for inverse join columns */
696
ForeignKey inverseForeignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
697
698
/** (Optional) Unique constraints on the join table */
699
UniqueConstraint[] uniqueConstraints() default {};
700
701
/** (Optional) Indexes for the join table */
702
Index[] indexes() default {};
703
}
704
705
/**
706
* Designates a ManyToOne or OneToOne relationship attribute for an EmbeddedId primary key
707
* @since 2.0
708
*/
709
@Target({METHOD, FIELD})
710
@Retention(RUNTIME)
711
public @interface MapsId {
712
/** (Optional) The name of the attribute within the composite key */
713
String value() default "";
714
}
715
```
716
717
**Usage Example:**
718
719
```java
720
// One-to-One
721
@Entity
722
public class User {
723
@Id
724
private Long id;
725
726
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
727
@JoinColumn(name = "profile_id")
728
private UserProfile profile;
729
}
730
731
// One-to-Many / Many-to-One (bidirectional)
732
@Entity
733
public class Department {
734
@Id
735
private Long id;
736
737
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
738
private List<Employee> employees = new ArrayList<>();
739
}
740
741
@Entity
742
public class Employee {
743
@Id
744
private Long id;
745
746
@ManyToOne(fetch = FetchType.LAZY)
747
@JoinColumn(name = "department_id", nullable = false)
748
private Department department;
749
}
750
751
// Many-to-Many
752
@Entity
753
public class Student {
754
@Id
755
private Long id;
756
757
@ManyToMany
758
@JoinTable(
759
name = "student_course",
760
joinColumns = @JoinColumn(name = "student_id"),
761
inverseJoinColumns = @JoinColumn(name = "course_id")
762
)
763
private Set<Course> courses = new HashSet<>();
764
}
765
766
@Entity
767
public class Course {
768
@Id
769
private Long id;
770
771
@ManyToMany(mappedBy = "courses")
772
private Set<Student> students = new HashSet<>();
773
}
774
```
775
776
### Collection Mappings
777
778
Map collections of basic types and embeddables.
779
780
```java { .api }
781
/**
782
* Specifies a collection of instances of a basic type or embeddable class
783
* @since 2.0
784
*/
785
@Target({METHOD, FIELD})
786
@Retention(RUNTIME)
787
public @interface ElementCollection {
788
/** (Optional) The basic or embeddable class that is the element type of the collection */
789
Class targetClass() default void.class;
790
791
/** (Optional) Whether the association should be lazily loaded or eagerly fetched */
792
FetchType fetch() default FetchType.LAZY;
793
}
794
795
/**
796
* Specifies the table that is used for the mapping of collections
797
* @since 2.0
798
*/
799
@Target({METHOD, FIELD})
800
@Retention(RUNTIME)
801
public @interface CollectionTable {
802
/** (Optional) The name of the collection table */
803
String name() default "";
804
805
/** (Optional) The catalog of the table */
806
String catalog() default "";
807
808
/** (Optional) The schema of the table */
809
String schema() default "";
810
811
/** (Optional) The foreign key columns of the collection table */
812
JoinColumn[] joinColumns() default {};
813
814
/** (Optional) The foreign key constraint specification */
815
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
816
817
/** (Optional) Unique constraints on the table */
818
UniqueConstraint[] uniqueConstraints() default {};
819
820
/** (Optional) Indexes for the table */
821
Index[] indexes() default {};
822
}
823
824
/**
825
* Specifies the ordering of collection elements
826
* @since 1.0
827
*/
828
@Target({METHOD, FIELD})
829
@Retention(RUNTIME)
830
public @interface OrderBy {
831
/** (Optional) The ordering clause */
832
String value() default "";
833
}
834
835
/**
836
* Specifies a column that is used to maintain the persistent order of a list
837
* @since 2.0
838
*/
839
@Target({METHOD, FIELD})
840
@Retention(RUNTIME)
841
public @interface OrderColumn {
842
/** (Optional) The name of the ordering column */
843
String name() default "";
844
845
/** (Optional) Whether the column is nullable */
846
boolean nullable() default true;
847
848
/** (Optional) Whether the column is included in SQL INSERT statements */
849
boolean insertable() default true;
850
851
/** (Optional) Whether the column is included in SQL UPDATE statements */
852
boolean updatable() default true;
853
854
/** (Optional) The SQL fragment for column definition */
855
String columnDefinition() default "";
856
}
857
```
858
859
**Usage Example:**
860
861
```java
862
@Entity
863
public class Person {
864
@Id
865
private Long id;
866
867
@ElementCollection
868
@CollectionTable(name = "phone_numbers", joinColumns = @JoinColumn(name = "person_id"))
869
@Column(name = "phone_number")
870
private Set<String> phoneNumbers = new HashSet<>();
871
872
@ElementCollection
873
@CollectionTable(name = "addresses")
874
@OrderColumn(name = "address_index")
875
private List<Address> addresses = new ArrayList<>();
876
}
877
```
878
879
### Map Collections
880
881
Map collections with custom keys.
882
883
```java { .api }
884
/**
885
* Specifies the map key for associations of type Map
886
* @since 1.0
887
*/
888
@Target({METHOD, FIELD})
889
@Retention(RUNTIME)
890
public @interface MapKey {
891
/** (Optional) The name of the persistent field or property of the map key */
892
String name() default "";
893
}
894
895
/**
896
* Specifies the type of the map key
897
* @since 2.0
898
*/
899
@Target({METHOD, FIELD})
900
@Retention(RUNTIME)
901
public @interface MapKeyClass {
902
/** The type of the map key */
903
Class value();
904
}
905
906
/**
907
* Specifies the mapped column for the map key
908
* @since 2.0
909
*/
910
@Target({METHOD, FIELD})
911
@Retention(RUNTIME)
912
public @interface MapKeyColumn {
913
/** (Optional) The name of the map key column */
914
String name() default "";
915
916
/** (Optional) Whether the column is unique */
917
boolean unique() default false;
918
919
/** (Optional) Whether the column is nullable */
920
boolean nullable() default false;
921
922
/** (Optional) Whether the column is insertable */
923
boolean insertable() default true;
924
925
/** (Optional) Whether the column is updatable */
926
boolean updatable() default true;
927
928
/** (Optional) The SQL fragment for column definition */
929
String columnDefinition() default "";
930
931
/** (Optional) The name of the table containing the column */
932
String table() default "";
933
934
/** (Optional) The column length */
935
int length() default 255;
936
937
/** (Optional) The precision for numeric columns */
938
int precision() default 0;
939
940
/** (Optional) The scale for numeric columns */
941
int scale() default 0;
942
}
943
944
/**
945
* Specifies the enum type for a map key
946
* @since 2.0
947
*/
948
@Target({METHOD, FIELD})
949
@Retention(RUNTIME)
950
public @interface MapKeyEnumerated {
951
/** (Optional) The type used in mapping the map key enum */
952
EnumType value() default EnumType.ORDINAL;
953
}
954
955
/**
956
* Specifies the temporal type for a map key
957
* @since 2.0
958
*/
959
@Target({METHOD, FIELD})
960
@Retention(RUNTIME)
961
public @interface MapKeyTemporal {
962
/** (Required) The temporal type for the map key */
963
TemporalType value();
964
}
965
966
/**
967
* Specifies a mapping to an entity that is a map key
968
* @since 2.0
969
*/
970
@Target({METHOD, FIELD})
971
@Retention(RUNTIME)
972
public @interface MapKeyJoinColumn {
973
/** (Optional) The name of the foreign key column for the map key */
974
String name() default "";
975
976
/** (Optional) The name of the column referenced by this foreign key column */
977
String referencedColumnName() default "";
978
979
/** (Optional) Whether the column is unique */
980
boolean unique() default false;
981
982
/** (Optional) Whether the column is nullable */
983
boolean nullable() default false;
984
985
/** (Optional) Whether the column is insertable */
986
boolean insertable() default true;
987
988
/** (Optional) Whether the column is updatable */
989
boolean updatable() default true;
990
991
/** (Optional) The SQL fragment for column definition */
992
String columnDefinition() default "";
993
994
/** (Optional) The name of the table containing the column */
995
String table() default "";
996
997
/** (Optional) The foreign key constraint specification */
998
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
999
}
1000
1001
/**
1002
* Specifies the mapping for composite map key join columns
1003
* @since 2.0
1004
*/
1005
@Target({METHOD, FIELD})
1006
@Retention(RUNTIME)
1007
public @interface MapKeyJoinColumns {
1008
/** Array of map key join columns */
1009
MapKeyJoinColumn[] value();
1010
1011
/** (Optional) The foreign key constraint specification */
1012
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
1013
}
1014
```
1015
1016
**Usage Example:**
1017
1018
```java
1019
@Entity
1020
public class Company {
1021
@Id
1022
private Long id;
1023
1024
@OneToMany
1025
@MapKey(name = "employeeId")
1026
private Map<String, Employee> employeesByNumber = new HashMap<>();
1027
1028
@ElementCollection
1029
@MapKeyColumn(name = "department_name")
1030
@Column(name = "budget")
1031
private Map<String, BigDecimal> departmentBudgets = new HashMap<>();
1032
}
1033
```
1034
1035
### Inheritance Mapping
1036
1037
Map entity inheritance hierarchies to database tables.
1038
1039
```java { .api }
1040
/**
1041
* Specifies the inheritance strategy for an entity class hierarchy
1042
* @since 1.0
1043
*/
1044
@Target(TYPE)
1045
@Retention(RUNTIME)
1046
public @interface Inheritance {
1047
/** (Optional) The strategy to use */
1048
InheritanceType strategy() default InheritanceType.SINGLE_TABLE;
1049
}
1050
1051
/**
1052
* Specifies the discriminator column for SINGLE_TABLE and JOINED inheritance
1053
* @since 1.0
1054
*/
1055
@Target(TYPE)
1056
@Retention(RUNTIME)
1057
public @interface DiscriminatorColumn {
1058
/** (Optional) The name of the discriminator column */
1059
String name() default "DTYPE";
1060
1061
/** (Optional) The type of object used to represent the discriminator column */
1062
DiscriminatorType discriminatorType() default DiscriminatorType.STRING;
1063
1064
/** (Optional) The SQL fragment for column definition */
1065
String columnDefinition() default "";
1066
1067
/** (Optional) The column length for STRING discriminator types */
1068
int length() default 31;
1069
}
1070
1071
/**
1072
* Specifies the value of the discriminator column for entities of the given type
1073
* @since 1.0
1074
*/
1075
@Target(TYPE)
1076
@Retention(RUNTIME)
1077
public @interface DiscriminatorValue {
1078
/** (Required) The discriminator value */
1079
String value();
1080
}
1081
1082
/**
1083
* Specifies a primary key column used as a foreign key to join to another table
1084
* @since 1.0
1085
*/
1086
@Target({METHOD, FIELD, TYPE})
1087
@Retention(RUNTIME)
1088
public @interface PrimaryKeyJoinColumn {
1089
/** (Optional) The name of the primary key column */
1090
String name() default "";
1091
1092
/** (Optional) The name of the primary key column of the referenced table */
1093
String referencedColumnName() default "";
1094
1095
/** (Optional) The SQL fragment for column definition */
1096
String columnDefinition() default "";
1097
1098
/** (Optional) The foreign key constraint specification */
1099
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
1100
}
1101
1102
/**
1103
* Groups PrimaryKeyJoinColumn annotations for composite foreign keys
1104
* @since 1.0
1105
*/
1106
@Target({TYPE})
1107
@Retention(RUNTIME)
1108
public @interface PrimaryKeyJoinColumns {
1109
/** Array of primary key join columns */
1110
PrimaryKeyJoinColumn[] value();
1111
1112
/** (Optional) The foreign key constraint specification */
1113
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
1114
}
1115
```
1116
1117
**Usage Example:**
1118
1119
```java
1120
// Single table inheritance
1121
@Entity
1122
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
1123
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
1124
public abstract class Vehicle {
1125
@Id
1126
private Long id;
1127
private String manufacturer;
1128
}
1129
1130
@Entity
1131
@DiscriminatorValue("CAR")
1132
public class Car extends Vehicle {
1133
private Integer numberOfDoors;
1134
}
1135
1136
@Entity
1137
@DiscriminatorValue("TRUCK")
1138
public class Truck extends Vehicle {
1139
private BigDecimal payloadCapacity;
1140
}
1141
1142
// Joined table inheritance
1143
@Entity
1144
@Inheritance(strategy = InheritanceType.JOINED)
1145
public abstract class Account {
1146
@Id
1147
private Long id;
1148
private String accountNumber;
1149
}
1150
1151
@Entity
1152
@PrimaryKeyJoinColumn(name = "account_id")
1153
public class SavingsAccount extends Account {
1154
private BigDecimal interestRate;
1155
}
1156
1157
@Entity
1158
@PrimaryKeyJoinColumn(name = "account_id")
1159
public class CheckingAccount extends Account {
1160
private BigDecimal overdraftLimit;
1161
}
1162
```
1163
1164
### Secondary Tables
1165
1166
Map a single entity to multiple tables.
1167
1168
```java { .api }
1169
/**
1170
* Specifies a secondary table for the annotated entity class
1171
* @since 1.0
1172
*/
1173
@Target(TYPE)
1174
@Retention(RUNTIME)
1175
public @interface SecondaryTable {
1176
/** (Required) The name of the secondary table */
1177
String name();
1178
1179
/** (Optional) The catalog of the table */
1180
String catalog() default "";
1181
1182
/** (Optional) The schema of the table */
1183
String schema() default "";
1184
1185
/** (Optional) The columns that are used to join with the primary table */
1186
PrimaryKeyJoinColumn[] pkJoinColumns() default {};
1187
1188
/** (Optional) The foreign key constraint specification */
1189
ForeignKey foreignKey() default @ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
1190
1191
/** (Optional) Unique constraints on the table */
1192
UniqueConstraint[] uniqueConstraints() default {};
1193
1194
/** (Optional) Indexes for the table */
1195
Index[] indexes() default {};
1196
}
1197
1198
/**
1199
* Specifies multiple secondary tables for an entity
1200
* @since 1.0
1201
*/
1202
@Target(TYPE)
1203
@Retention(RUNTIME)
1204
public @interface SecondaryTables {
1205
/** Array of secondary tables */
1206
SecondaryTable[] value();
1207
}
1208
```
1209
1210
**Usage Example:**
1211
1212
```java
1213
@Entity
1214
@Table(name = "employee")
1215
@SecondaryTable(name = "employee_details",
1216
pkJoinColumns = @PrimaryKeyJoinColumn(name = "employee_id"))
1217
public class Employee {
1218
@Id
1219
private Long id;
1220
1221
@Column(name = "name")
1222
private String name;
1223
1224
@Column(table = "employee_details")
1225
private String biography;
1226
1227
@Column(table = "employee_details")
1228
private byte[] photo;
1229
}
1230
```
1231
1232
### Constraints and Indexes
1233
1234
Define database constraints and indexes.
1235
1236
```java { .api }
1237
/**
1238
* Specifies that a unique constraint is to be included in the generated DDL
1239
* @since 1.0
1240
*/
1241
@Target({})
1242
@Retention(RUNTIME)
1243
public @interface UniqueConstraint {
1244
/** (Optional) Constraint name */
1245
String name() default "";
1246
1247
/** (Required) An array of column names that make up the constraint */
1248
String[] columnNames();
1249
}
1250
1251
/**
1252
* Used in schema generation to specify creation of an index
1253
* @since 2.1
1254
*/
1255
@Target({})
1256
@Retention(RUNTIME)
1257
public @interface Index {
1258
/** (Optional) The name of the index */
1259
String name() default "";
1260
1261
/** (Required) The list of columns for the index */
1262
String columnList();
1263
1264
/** (Optional) Whether the index is unique */
1265
boolean unique() default false;
1266
}
1267
1268
/**
1269
* Used to specify the handling of foreign key constraints
1270
* @since 2.1
1271
*/
1272
@Target({})
1273
@Retention(RUNTIME)
1274
public @interface ForeignKey {
1275
/** (Optional) The name of the foreign key constraint */
1276
String name() default "";
1277
1278
/** (Optional) The constraint mode */
1279
ConstraintMode value() default ConstraintMode.PROVIDER_DEFAULT;
1280
1281
/** (Optional) The foreign key constraint definition */
1282
String foreignKeyDefinition() default "";
1283
}
1284
```
1285
1286
### Access Type
1287
1288
Specify field or property access for entities.
1289
1290
```java { .api }
1291
/**
1292
* Used to specify an access type for an entity class, mapped superclass, or embeddable class
1293
* @since 2.0
1294
*/
1295
@Target({TYPE, METHOD, FIELD})
1296
@Retention(RUNTIME)
1297
public @interface Access {
1298
/** (Required) The access type */
1299
AccessType value();
1300
}
1301
```
1302
1303
**Usage Example:**
1304
1305
```java
1306
@Entity
1307
@Access(AccessType.FIELD)
1308
public class Product {
1309
@Id
1310
private Long id;
1311
1312
private String name;
1313
1314
@Access(AccessType.PROPERTY)
1315
@Column(name = "price")
1316
public BigDecimal getPrice() {
1317
return price.setScale(2, RoundingMode.HALF_UP);
1318
}
1319
1320
public void setPrice(BigDecimal price) {
1321
this.price = price;
1322
}
1323
1324
private BigDecimal price;
1325
}
1326
```
1327
1328
### Attribute Converters
1329
1330
Convert entity attribute values to database column values.
1331
1332
```java { .api }
1333
/**
1334
* Specifies the conversion of a Basic field or property
1335
* @since 2.1
1336
*/
1337
@Target({METHOD, FIELD, TYPE})
1338
@Retention(RUNTIME)
1339
@Repeatable(Converts.class)
1340
public @interface Convert {
1341
/** (Optional) The converter class */
1342
Class converter() default void.class;
1343
1344
/** (Optional) The name of the attribute to which the converter is applied */
1345
String attributeName() default "";
1346
1347
/** (Optional) Whether to disable conversion */
1348
boolean disableConversion() default false;
1349
}
1350
1351
/**
1352
* Used to group Convert annotations
1353
* @since 2.1
1354
*/
1355
@Target({METHOD, FIELD, TYPE})
1356
@Retention(RUNTIME)
1357
public @interface Converts {
1358
/** Array of converts */
1359
Convert[] value();
1360
}
1361
1362
/**
1363
* Specifies that the annotated class is a converter
1364
* @since 2.1
1365
*/
1366
@Target(TYPE)
1367
@Retention(RUNTIME)
1368
public @interface Converter {
1369
/** (Optional) Whether the converter should be auto-applied */
1370
boolean autoApply() default false;
1371
}
1372
1373
/**
1374
* Interface for entity attribute value conversion
1375
* @since 2.1
1376
*/
1377
public interface AttributeConverter<X, Y> {
1378
/**
1379
* Converts the entity attribute value to database column value
1380
* @param attribute the entity attribute value
1381
* @return the database column value
1382
*/
1383
Y convertToDatabaseColumn(X attribute);
1384
1385
/**
1386
* Converts the database column value to entity attribute value
1387
* @param dbData the database column value
1388
* @return the entity attribute value
1389
*/
1390
X convertToEntityAttribute(Y dbData);
1391
}
1392
```
1393
1394
**Usage Example:**
1395
1396
```java
1397
@Converter(autoApply = true)
1398
public class BooleanToYNConverter implements AttributeConverter<Boolean, String> {
1399
@Override
1400
public String convertToDatabaseColumn(Boolean attribute) {
1401
return attribute != null && attribute ? "Y" : "N";
1402
}
1403
1404
@Override
1405
public Boolean convertToEntityAttribute(String dbData) {
1406
return "Y".equals(dbData);
1407
}
1408
}
1409
1410
@Entity
1411
public class Customer {
1412
@Id
1413
private Long id;
1414
1415
@Convert(converter = BooleanToYNConverter.class)
1416
private Boolean active;
1417
}
1418
```
1419
1420
### Entity Graphs
1421
1422
Define named entity graphs for optimizing fetch strategies and controlling which associations should be loaded.
1423
1424
```java { .api }
1425
/**
1426
* Used to specify the path and boundaries for a find operation or query
1427
* @since 2.1
1428
*/
1429
@Repeatable(NamedEntityGraphs.class)
1430
@Target(TYPE)
1431
@Retention(RUNTIME)
1432
public @interface NamedEntityGraph {
1433
/**
1434
* (Optional) The name of the entity graph. Defaults to the entity name of the root entity
1435
*/
1436
String name() default "";
1437
1438
/**
1439
* A list of attributes of the entity that are included in this graph
1440
*/
1441
NamedAttributeNode[] attributeNodes() default {};
1442
1443
/**
1444
* Include all of the attributes of the annotated entity class as attribute nodes
1445
*/
1446
boolean includeAllAttributes() default false;
1447
1448
/**
1449
* A list of subgraphs that are included in the entity graph
1450
*/
1451
NamedSubgraph[] subgraphs() default {};
1452
1453
/**
1454
* A list of subgraphs that will add additional attributes for subclasses
1455
*/
1456
NamedSubgraph[] subclassSubgraphs() default {};
1457
}
1458
1459
/**
1460
* Used to group NamedEntityGraph annotations
1461
* @since 2.1
1462
*/
1463
@Target(TYPE)
1464
@Retention(RUNTIME)
1465
public @interface NamedEntityGraphs {
1466
/** Array of NamedEntityGraph annotations */
1467
NamedEntityGraph[] value();
1468
}
1469
1470
/**
1471
* A member element of a NamedEntityGraph
1472
* @since 2.1
1473
*/
1474
@Target({})
1475
@Retention(RUNTIME)
1476
public @interface NamedAttributeNode {
1477
/**
1478
* The name of the attribute that must be included in the graph
1479
*/
1480
String value();
1481
1482
/**
1483
* If the attribute references a managed type, refer to that NamedSubgraph definition
1484
*/
1485
String subgraph() default "";
1486
1487
/**
1488
* If the attribute references a Map, specify a subgraph for the Entity key type
1489
*/
1490
String keySubgraph() default "";
1491
}
1492
1493
/**
1494
* A member element of a NamedEntityGraph, referenced from NamedAttributeNode
1495
* @since 2.1
1496
*/
1497
@Target({})
1498
@Retention(RUNTIME)
1499
public @interface NamedSubgraph {
1500
/**
1501
* The name of the subgraph as referenced from a NamedAttributeNode element
1502
*/
1503
String name();
1504
1505
/**
1506
* The type represented by this subgraph
1507
*/
1508
Class type() default void.class;
1509
1510
/**
1511
* The list of attributes of the class that must be included
1512
*/
1513
NamedAttributeNode[] attributeNodes();
1514
}
1515
```
1516
1517
**Usage Example:**
1518
1519
```java
1520
@Entity
1521
@NamedEntityGraph(
1522
name = "Order.detail",
1523
attributeNodes = {
1524
@NamedAttributeNode("customer"),
1525
@NamedAttributeNode(value = "items", subgraph = "items.detail")
1526
},
1527
subgraphs = {
1528
@NamedSubgraph(
1529
name = "items.detail",
1530
attributeNodes = {
1531
@NamedAttributeNode("product"),
1532
@NamedAttributeNode("quantity")
1533
}
1534
)
1535
}
1536
)
1537
public class Order {
1538
@Id
1539
private Long id;
1540
1541
@ManyToOne
1542
private Customer customer;
1543
1544
@OneToMany
1545
private List<OrderItem> items;
1546
}
1547
1548
// Use the entity graph
1549
EntityGraph<?> graph = em.getEntityGraph("Order.detail");
1550
Map<String, Object> props = new HashMap<>();
1551
props.put("jakarta.persistence.fetchgraph", graph);
1552
Order order = em.find(Order.class, orderId, props);
1553
```
1554
1555
### Container and CDI Injection
1556
1557
Annotations for dependency injection of persistence contexts and entity manager factories in Jakarta EE containers.
1558
1559
```java { .api }
1560
/**
1561
* Expresses a dependency on a container-managed EntityManager
1562
* @since 1.0
1563
*/
1564
@Repeatable(PersistenceContexts.class)
1565
@Target({TYPE, METHOD, FIELD})
1566
@Retention(RUNTIME)
1567
public @interface PersistenceContext {
1568
/**
1569
* (Optional) The name by which the entity manager is to be accessed
1570
*/
1571
String name() default "";
1572
1573
/**
1574
* (Optional) The name of the persistence unit as defined in persistence.xml
1575
*/
1576
String unitName() default "";
1577
1578
/**
1579
* (Optional) Specifies whether a transaction-scoped or extended persistence context is used
1580
*/
1581
PersistenceContextType type() default PersistenceContextType.TRANSACTION;
1582
1583
/**
1584
* (Optional) Specifies whether the persistence context is automatically synchronized
1585
* @since 2.1
1586
*/
1587
SynchronizationType synchronization() default SynchronizationType.SYNCHRONIZED;
1588
1589
/**
1590
* (Optional) Properties for the container or persistence provider
1591
*/
1592
PersistenceProperty[] properties() default {};
1593
}
1594
1595
/**
1596
* Declares one or more PersistenceContext annotations
1597
* @since 1.0
1598
*/
1599
@Target(TYPE)
1600
@Retention(RUNTIME)
1601
public @interface PersistenceContexts {
1602
/** One or more PersistenceContext annotations */
1603
PersistenceContext[] value();
1604
}
1605
1606
/**
1607
* Expresses a dependency on an EntityManagerFactory
1608
* @since 1.0
1609
*/
1610
@Repeatable(PersistenceUnits.class)
1611
@Target({TYPE, METHOD, FIELD})
1612
@Retention(RUNTIME)
1613
public @interface PersistenceUnit {
1614
/**
1615
* (Optional) The name by which the entity manager factory is to be accessed
1616
*/
1617
String name() default "";
1618
1619
/**
1620
* (Optional) The name of the persistence unit as defined in persistence.xml
1621
*/
1622
String unitName() default "";
1623
}
1624
1625
/**
1626
* Declares one or more PersistenceUnit annotations
1627
* @since 1.0
1628
*/
1629
@Target(TYPE)
1630
@Retention(RUNTIME)
1631
public @interface PersistenceUnits {
1632
/** One or more PersistenceUnit annotations */
1633
PersistenceUnit[] value();
1634
}
1635
1636
/**
1637
* Describes a single container or persistence provider property
1638
* @since 1.0
1639
*/
1640
@Target({})
1641
@Retention(RUNTIME)
1642
public @interface PersistenceProperty {
1643
/** The name of the property */
1644
String name();
1645
1646
/** The value of the property */
1647
String value();
1648
}
1649
```
1650
1651
**Usage Example:**
1652
1653
```java
1654
@Stateless
1655
public class OrderService {
1656
// Inject EntityManager
1657
@PersistenceContext(unitName = "orderDB")
1658
private EntityManager em;
1659
1660
// Inject EntityManagerFactory
1661
@PersistenceUnit(unitName = "orderDB")
1662
private EntityManagerFactory emf;
1663
1664
// With properties
1665
@PersistenceContext(
1666
unitName = "orderDB",
1667
type = PersistenceContextType.EXTENDED,
1668
properties = {
1669
@PersistenceProperty(name = "jakarta.persistence.cache.storeMode", value = "REFRESH")
1670
}
1671
)
1672
private EntityManager extendedEm;
1673
1674
public void processOrder(Long orderId) {
1675
Order order = em.find(Order.class, orderId);
1676
// Process order
1677
}
1678
}
1679
```
1680