Files
hibernate-demo/src/main/java/com/ankurm/hibernatedemo/persistenceannotations/MixedAccessEntity.java
T

77 lines
2.4 KiB
Java
Executable File

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;
}
}