or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdentity-mapping.mdindex.mdqueries.mdsession-management.mdtransactions.mdtype-system.md

entity-mapping.mddocs/

0

# Entity Mapping

1

2

Hibernate Core provides extensive annotations and mapping capabilities beyond the standard JPA annotations. These include advanced caching, fetching strategies, custom types, natural identifiers, and specialized entity behaviors.

3

4

## Capabilities

5

6

### Caching Annotations

7

8

Advanced second-level caching configuration for entities and collections.

9

10

```java { .api }

11

/**

12

* Configures second-level caching for an entity or collection

13

*/

14

@Target({TYPE, METHOD, FIELD})

15

@Retention(RUNTIME)

16

public @interface Cache {

17

/**

18

* Cache concurrency strategy

19

* @return the concurrency strategy

20

*/

21

CacheConcurrencyStrategy usage();

22

23

/**

24

* Cache region name

25

* @return the region name (defaults to entity/collection name)

26

*/

27

String region() default "";

28

29

/**

30

* Include lazy attributes in cache when loaded

31

* @return whether to cache lazy fields (default true)

32

*/

33

boolean includeLazy() default true;

34

}

35

36

/**

37

* Cache concurrency strategies

38

*/

39

public enum CacheConcurrencyStrategy {

40

/** No concurrency strategy specified */

41

NONE,

42

/** Read-only access - immutable objects */

43

READ_ONLY,

44

/** Read/write access with no locking - for rarely updated data */

45

NONSTRICT_READ_WRITE,

46

/** Read/write access with soft locks - for commonly updated data */

47

READ_WRITE,

48

/** Transactional access - requires JTA/XA integration */

49

TRANSACTIONAL

50

}

51

```

52

53

### Cache Runtime Interface

54

55

Runtime interface for programmatic cache interaction and management.

56

57

```java { .api }

58

/**

59

* Runtime cache interface for programmatic cache operations

60

*/

61

public interface Cache {

62

/**

63

* Get an item from the cache

64

* @param key the cache key

65

* @return the cached item or null if not found

66

*/

67

Object get(Object key);

68

69

/**

70

* Put an item in the cache

71

* @param key the cache key

72

* @param value the value to cache

73

*/

74

void put(Object key, Object value);

75

76

/**

77

* Remove an item from the cache

78

* @param key the cache key

79

*/

80

void evict(Object key);

81

82

/**

83

* Clear all entries from the cache

84

*/

85

void clear();

86

87

/**

88

* Destroy/close the cache

89

*/

90

void destroy();

91

92

/**

93

* Get the cache region name

94

* @return the region name

95

*/

96

String getRegionName();

97

98

/**

99

* Check if the cache contains the specified key

100

* @param key the cache key

101

* @return true if key exists in cache

102

*/

103

boolean contains(Object key);

104

105

/**

106

* Get cache statistics

107

* @return CacheStatistics instance or null if statistics disabled

108

*/

109

CacheStatistics getStatistics();

110

}

111

112

/**

113

* Cache statistics interface

114

*/

115

public interface CacheStatistics {

116

/**

117

* Get the number of cache hits

118

* @return hit count

119

*/

120

long getHitCount();

121

122

/**

123

* Get the number of cache misses

124

* @return miss count

125

*/

126

long getMissCount();

127

128

/**

129

* Get the cache hit ratio

130

* @return hit ratio (0.0 to 1.0)

131

*/

132

double getHitRatio();

133

134

/**

135

* Get the number of cached elements

136

* @return element count

137

*/

138

long getElementCountInMemory();

139

140

/**

141

* Clear the statistics

142

*/

143

void clear();

144

}

145

```

146

147

### Fetching Strategy Annotations

148

149

Control how associations are fetched from the database.

150

151

```java { .api }

152

/**

153

* Specifies the fetch strategy for an association

154

*/

155

@Target({METHOD, FIELD})

156

@Retention(RUNTIME)

157

public @interface Fetch {

158

/**

159

* The fetch mode to use

160

* @return the fetch mode

161

*/

162

FetchMode value();

163

}

164

165

/**

166

* Available fetch modes

167

*/

168

public enum FetchMode {

169

/** Use a select statement to load the association */

170

SELECT,

171

/** Use an outer join to load the association */

172

JOIN,

173

/** Use a subquery to load the association */

174

SUBSELECT

175

}

176

177

/**

178

* Batch size for fetching associations or entities

179

*/

180

@Target({TYPE, METHOD, FIELD})

181

@Retention(RUNTIME)

182

public @interface BatchSize {

183

/**

184

* The batch size

185

* @return the batch size (must be positive)

186

*/

187

int size();

188

}

189

190

/**

191

* Lazy loading group for fine-grained lazy loading

192

*/

193

@Target({METHOD, FIELD})

194

@Retention(RUNTIME)

195

public @interface LazyGroup {

196

/**

197

* The lazy group name

198

* @return the group name

199

*/

200

String value();

201

}

202

```

203

204

### Natural Identifier Annotations

205

206

Support for natural identifiers as alternatives to surrogate keys.

207

208

```java { .api }

209

/**

210

* Marks a property as part of the natural identifier

211

*/

212

@Target({METHOD, FIELD})

213

@Retention(RUNTIME)

214

public @interface NaturalId {

215

/**

216

* Whether the natural ID is mutable

217

* @return true if mutable

218

*/

219

boolean mutable() default false;

220

}

221

222

/**

223

* Cache configuration specifically for natural ID lookups

224

*/

225

@Target(TYPE)

226

@Retention(RUNTIME)

227

public @interface NaturalIdCache {

228

/**

229

* Cache region for natural ID lookups

230

* @return the cache region name

231

*/

232

String region() default "";

233

}

234

```

235

236

### Custom Type Annotations

237

238

Specify custom types for properties and parameters.

239

240

```java { .api }

241

/**

242

* Specifies a custom Hibernate type for a property

243

*/

244

@Target({METHOD, FIELD})

245

@Retention(RUNTIME)

246

public @interface Type {

247

/**

248

* The type implementation class

249

* @return the type class

250

*/

251

Class<? extends UserType<?>> value() default void.class;

252

253

/**

254

* Parameters for the type

255

* @return array of parameters

256

*/

257

Parameter[] parameters() default {};

258

}

259

260

/**

261

* Specify Java type for a property

262

*/

263

@Target({METHOD, FIELD, PARAMETER})

264

@Retention(RUNTIME)

265

public @interface JavaType {

266

/**

267

* The Java type descriptor class

268

* @return the descriptor class

269

*/

270

Class<? extends JavaTypeDescriptor<?>> value();

271

}

272

273

/**

274

* Specify JDBC type for a property

275

*/

276

@Target({METHOD, FIELD})

277

@Retention(RUNTIME)

278

public @interface JdbcType {

279

/**

280

* The JDBC type descriptor class

281

* @return the descriptor class

282

*/

283

Class<? extends JdbcType> value();

284

}

285

```

286

287

### Entity Behavior Annotations

288

289

Control entity lifecycle and behavior.

290

291

```java { .api }

292

/**

293

* Entity is immutable (read-only)

294

*/

295

@Target(TYPE)

296

@Retention(RUNTIME)

297

public @interface Immutable {

298

}

299

300

/**

301

* Generate SQL dynamically for inserts

302

*/

303

@Target(TYPE)

304

@Retention(RUNTIME)

305

public @interface DynamicInsert {

306

/**

307

* Whether to use dynamic inserts

308

* @return true for dynamic inserts

309

*/

310

boolean value() default true;

311

}

312

313

/**

314

* Generate SQL dynamically for updates

315

*/

316

@Target(TYPE)

317

@Retention(RUNTIME)

318

public @interface DynamicUpdate {

319

/**

320

* Whether to use dynamic updates

321

* @return true for dynamic updates

322

*/

323

boolean value() default true;

324

}

325

326

/**

327

* Select before update optimization

328

*/

329

@Target(TYPE)

330

@Retention(RUNTIME)

331

public @interface SelectBeforeUpdate {

332

/**

333

* Whether to select before update

334

* @return true to select before update

335

*/

336

boolean value() default true;

337

}

338

339

/**

340

* Optimistic locking strategy

341

*/

342

@Target(TYPE)

343

@Retention(RUNTIME)

344

public @interface OptimisticLocking {

345

/**

346

* The optimistic locking type

347

* @return the locking type

348

*/

349

OptimisticLockType type() default OptimisticLockType.VERSION;

350

}

351

352

/**

353

* Optimistic locking types

354

*/

355

public enum OptimisticLockType {

356

/** No optimistic locking */

357

NONE,

358

/** Version-based locking */

359

VERSION,

360

/** Dirty fields locking */

361

DIRTY,

362

/** All fields locking */

363

ALL

364

}

365

```

366

367

### Timestamp and Generated Value Annotations

368

369

Automatic timestamp and value generation.

370

371

```java { .api }

372

/**

373

* Automatically set creation timestamp

374

*/

375

@Target({METHOD, FIELD})

376

@Retention(RUNTIME)

377

public @interface CreationTimestamp {

378

}

379

380

/**

381

* Automatically set update timestamp

382

*/

383

@Target({METHOD, FIELD})

384

@Retention(RUNTIME)

385

public @interface UpdateTimestamp {

386

}

387

388

/**

389

* Specify generation strategy for properties

390

*/

391

@Target({METHOD, FIELD})

392

@Retention(RUNTIME)

393

public @interface Generated {

394

/**

395

* When the value is generated

396

* @return the generation timing

397

*/

398

GenerationTime value();

399

}

400

401

/**

402

* Generation timing options

403

*/

404

public enum GenerationTime {

405

/** Never generated */

406

NEVER,

407

/** Generated on insert only */

408

INSERT,

409

/** Generated on insert and update */

410

ALWAYS

411

}

412

```

413

414

### Formula and Computed Properties

415

416

Define computed properties and SQL formulas.

417

418

```java { .api }

419

/**

420

* SQL formula for computed properties

421

*/

422

@Target({METHOD, FIELD})

423

@Retention(RUNTIME)

424

public @interface Formula {

425

/**

426

* The SQL formula

427

* @return the SQL expression

428

*/

429

String value();

430

}

431

432

/**

433

* Derived property based on other properties

434

*/

435

@Target({METHOD, FIELD})

436

@Retention(RUNTIME)

437

public @interface ColumnTransformer {

438

/**

439

* SQL expression for reading the column

440

* @return the read expression

441

*/

442

String read() default "";

443

444

/**

445

* SQL expression for writing the column

446

* @return the write expression

447

*/

448

String write() default "";

449

}

450

```

451

452

### Collection and Association Annotations

453

454

Advanced collection and association mapping.

455

456

```java { .api }

457

/**

458

* Order collection by SQL expression

459

*/

460

@Target({METHOD, FIELD})

461

@Retention(RUNTIME)

462

public @interface OrderBy {

463

/**

464

* SQL ORDER BY clause

465

* @return the ordering clause

466

*/

467

String clause();

468

}

469

470

/**

471

* Sort collection in memory

472

*/

473

@Target({METHOD, FIELD})

474

@Retention(RUNTIME)

475

public @interface Sort {

476

/**

477

* The sorting type

478

* @return the sort type

479

*/

480

SortType type() default SortType.UNSORTED;

481

482

/**

483

* Comparator class for custom sorting

484

* @return the comparator class

485

*/

486

Class<? extends Comparator> comparator() default void.class;

487

}

488

489

/**

490

* How to handle missing referenced entities

491

*/

492

@Target({METHOD, FIELD})

493

@Retention(RUNTIME)

494

public @interface NotFound {

495

/**

496

* The action to take for missing references

497

* @return the not found action

498

*/

499

NotFoundAction action() default NotFoundAction.EXCEPTION;

500

}

501

502

/**

503

* Actions for missing references

504

*/

505

public enum NotFoundAction {

506

/** Throw exception */

507

EXCEPTION,

508

/** Ignore missing reference */

509

IGNORE

510

}

511

512

/**

513

* Database cascade actions

514

*/

515

@Target({METHOD, FIELD})

516

@Retention(RUNTIME)

517

public @interface OnDelete {

518

/**

519

* The cascade action

520

* @return the delete action

521

*/

522

OnDeleteAction action();

523

}

524

525

/**

526

* Database cascade actions

527

*/

528

public enum OnDeleteAction {

529

/** No action */

530

NO_ACTION,

531

/** Cascade delete */

532

CASCADE,

533

/** Set to null */

534

SET_NULL,

535

/** Set to default */

536

SET_DEFAULT,

537

/** Restrict delete */

538

RESTRICT

539

}

540

```

541

542

### Query and Filter Annotations

543

544

Named queries and entity filtering.

545

546

```java { .api }

547

/**

548

* Named HQL/JPQL query

549

*/

550

@Target(TYPE)

551

@Retention(RUNTIME)

552

@Repeatable(NamedQueries.class)

553

public @interface NamedQuery {

554

/**

555

* Query name

556

* @return the query name

557

*/

558

String name();

559

560

/**

561

* HQL/JPQL query string

562

* @return the query string

563

*/

564

String query();

565

566

/**

567

* Query hints

568

* @return array of query hints

569

*/

570

QueryHint[] hints() default {};

571

}

572

573

/**

574

* Named native SQL query

575

*/

576

@Target(TYPE)

577

@Retention(RUNTIME)

578

@Repeatable(NamedNativeQueries.class)

579

public @interface NamedNativeQuery {

580

/**

581

* Query name

582

* @return the query name

583

*/

584

String name();

585

586

/**

587

* Native SQL query string

588

* @return the SQL string

589

*/

590

String query();

591

592

/**

593

* Result class

594

* @return the result class

595

*/

596

Class resultClass() default void.class;

597

598

/**

599

* Result set mapping name

600

* @return the mapping name

601

*/

602

String resultSetMapping() default "";

603

}

604

605

/**

606

* Define a filter for the entity

607

*/

608

@Target(TYPE)

609

@Retention(RUNTIME)

610

@Repeatable(Filters.class)

611

public @interface Filter {

612

/**

613

* Filter name

614

* @return the filter name

615

*/

616

String name();

617

618

/**

619

* Filter condition

620

* @return the SQL condition

621

*/

622

String condition() default "";

623

}

624

625

/**

626

* Filter definition with parameters

627

*/

628

@Target(TYPE)

629

@Retention(RUNTIME)

630

@Repeatable(FilterDefs.class)

631

public @interface FilterDef {

632

/**

633

* Filter name

634

* @return the filter name

635

*/

636

String name();

637

638

/**

639

* Filter parameters

640

* @return array of parameters

641

*/

642

ParamDef[] parameters() default {};

643

644

/**

645

* Default condition

646

* @return the default condition

647

*/

648

String defaultCondition() default "";

649

}

650

```

651

652

## Usage Examples

653

654

### Entity with Caching and Natural ID

655

656

```java

657

@Entity

658

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "users")

659

@NaturalIdCache

660

@DynamicUpdate

661

@SelectBeforeUpdate

662

public class User {

663

@Id

664

@GeneratedValue(strategy = GenerationType.IDENTITY)

665

private Long id;

666

667

@NaturalId(mutable = false)

668

@Column(unique = true, nullable = false)

669

private String username;

670

671

@Column(nullable = false)

672

private String name;

673

674

@CreationTimestamp

675

@Column(name = "created_date")

676

private LocalDateTime createdDate;

677

678

@UpdateTimestamp

679

@Column(name = "last_modified")

680

private LocalDateTime lastModified;

681

682

// Computed property

683

@Formula("(SELECT COUNT(*) FROM orders o WHERE o.customer_id = id)")

684

private int orderCount;

685

686

// Constructors, getters, setters

687

}

688

```

689

690

### Advanced Association Mapping

691

692

```java

693

@Entity

694

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

695

@FilterDef(name = "activeOrders", parameters = @ParamDef(name = "status", type = String.class))

696

public class Customer {

697

@Id

698

private Long id;

699

700

private String name;

701

702

@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = CascadeType.ALL)

703

@Fetch(FetchMode.SUBSELECT)

704

@BatchSize(size = 10)

705

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

706

@OrderBy("orderDate DESC")

707

@Filter(name = "activeOrders", condition = "status = :status")

708

private Set<Order> orders = new HashSet<>();

709

710

@ManyToOne(fetch = FetchType.LAZY)

711

@JoinColumn(name = "address_id")

712

@NotFound(action = NotFoundAction.IGNORE)

713

@OnDelete(action = OnDeleteAction.SET_NULL)

714

private Address primaryAddress;

715

716

// Constructors, getters, setters

717

}

718

```

719

720

### Custom Type Usage

721

722

```java

723

@Entity

724

public class Product {

725

@Id

726

private Long id;

727

728

private String name;

729

730

// Custom type for monetary values

731

@Type(value = MoneyType.class)

732

@Column(name = "price")

733

private Money price;

734

735

// JSON type mapping

736

@Type(value = JsonType.class)

737

@Column(name = "attributes", columnDefinition = "json")

738

private Map<String, Object> attributes;

739

740

// Custom Java type

741

@JavaType(UUIDJavaType.class)

742

@Column(name = "external_id")

743

private UUID externalId;

744

745

// Encrypted field

746

@ColumnTransformer(

747

read = "AES_DECRYPT(credit_card, 'key')",

748

write = "AES_ENCRYPT(?, 'key')"

749

)

750

@Column(name = "credit_card")

751

private String creditCard;

752

753

// Constructors, getters, setters

754

}

755

```

756

757

### Immutable Entity with Formula

758

759

```java

760

@Entity

761

@Immutable

762

@Table(name = "order_summary_view")

763

public class OrderSummary {

764

@Id

765

private Long orderId;

766

767

private String customerName;

768

769

@Formula("(SELECT SUM(oi.quantity * oi.price) FROM order_items oi WHERE oi.order_id = order_id)")

770

private BigDecimal totalAmount;

771

772

@Formula("(SELECT COUNT(*) FROM order_items oi WHERE oi.order_id = order_id)")

773

private Integer itemCount;

774

775

@Type(value = PostgreSQLEnumType.class)

776

@Column(name = "status", columnDefinition = "order_status")

777

private OrderStatus status;

778

779

// Constructors, getters, setters (no setters for immutable entity)

780

}

781

```

782

783

### Using Filters

784

785

```java

786

// Enable filter for active records only

787

@Entity

788

@FilterDef(name = "activeOnly", defaultCondition = "active = true")

789

@Filter(name = "activeOnly")

790

public class Employee {

791

@Id

792

private Long id;

793

794

private String name;

795

796

private boolean active;

797

798

// Entity definition

799

}

800

801

// Usage in session

802

session.enableFilter("activeOnly");

803

List<Employee> activeEmployees = session.createQuery("FROM Employee", Employee.class)

804

.getResultList(); // Only returns active employees

805

806

// Filter with parameters

807

session.enableFilter("activeOrders")

808

.setParameter("status", "ACTIVE");

809

```

810

811

### Lazy Loading Groups

812

813

```java

814

@Entity

815

public class Document {

816

@Id

817

private Long id;

818

819

private String title;

820

821

// Metadata loaded eagerly

822

private String author;

823

private LocalDateTime createdDate;

824

825

// Content loaded lazily in separate group

826

@Basic(fetch = FetchType.LAZY)

827

@LazyGroup("content")

828

@Lob

829

private String content;

830

831

// Binary data loaded lazily in separate group

832

@Basic(fetch = FetchType.LAZY)

833

@LazyGroup("binary")

834

@Lob

835

private byte[] attachments;

836

837

// Constructors, getters, setters

838

}

839

```

840

841

## Mapping Best Practices

842

843

### Performance Considerations

844

845

- Use `@Cache` judiciously on frequently read, infrequently modified entities

846

- Implement `@BatchSize` for associations to avoid N+1 queries

847

- Use `@LazyGroup` to separate rarely accessed large properties

848

- Consider `@DynamicUpdate` for entities with many nullable columns

849

850

### Natural Identifiers

851

852

- Use `@NaturalId` for business keys (username, email, etc.)

853

- Enable `@NaturalIdCache` for frequently accessed natural IDs

854

- Keep natural IDs immutable when possible

855

856

### Custom Types

857

858

- Implement custom types for domain-specific value objects

859

- Use `@Type` for complex mappings that don't fit standard types

860

- Consider `@Formula` for computed properties that don't need persistence