Add Hibernate 7 batches 2-5: mapping styles, JPA annotations, natural IDs, @Immutable, stored procedures, in-memory test databases, JNDI mocking, proxies, associations, temporal mapping and named queries (Hibernate 7.4.5.Final + Spring Boot 4.1.1 + JDK 25)

This commit is contained in:
2026-09-06 10:30:19 +05:30
commit 5b97a85fe7
229 changed files with 17349 additions and 0 deletions
@@ -0,0 +1,76 @@
package com.ankurm.hibernatedemo.persistenceannotations;
import jakarta.persistence.Access;
import jakarta.persistence.AccessType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Transient;
/**
* Default access is FIELD (because {@code @Id} is annotated on the field). One property,
* {@code computedLabel}, is explicitly switched to PROPERTY access via {@code @Access} on its
* getter, with a derivation the FIELD side does not know about. This reproduces the classic
* "mixed access silently reads the wrong value" symptom: a raw field mutation is invisible to
* Hibernate once a property is PROPERTY-access, and vice versa.
*
* <p>Docs: docs/05-jpa-persistence-annotations.md, Topic 2.
*/
@Entity
public class MixedAccessEntity {
@Id
@GeneratedValue
private Long id;
private String rawValue;
// FIELD access is the entity default (because @Id is on a field). This backing field is
// deliberately never read directly by Hibernate for the "label" property -- only the
// PROPERTY-access getter below is.
@Transient
private int getterCallCount = 0;
public MixedAccessEntity() {
}
public MixedAccessEntity(String rawValue) {
this.rawValue = rawValue;
}
public Long getId() {
return id;
}
public String getRawValue() {
return rawValue;
}
public void setRawValue(String rawValue) {
this.rawValue = rawValue;
}
/**
* Explicitly PROPERTY access: Hibernate calls this getter (not a field read) to determine
* the persisted value for the "computedLabel" mapped property.
*/
@Access(AccessType.PROPERTY)
@Column(name = "computed_label")
public String getComputedLabel() {
getterCallCount++;
return rawValue == null ? null : rawValue.toUpperCase();
}
// Hibernate's default PROPERTY-access strategy REQUIRES a setter even for a logically
// read-only derived column -- omitting it throws PropertyNotFoundException at boot
// ("Could not locate setter method for property 'computedLabel'"). This setter is a
// deliberate no-op: it exists purely to satisfy that requirement.
public void setComputedLabel(String ignored) {
// no-op: computedLabel is derived from rawValue, never written directly
}
public int getGetterCallCount() {
return getterCallCount;
}
}