Access strategies
As a JPA provider, Hibernate can introspect both the entity attributes (instance fields) or the accessors (instance properties).
By default, the placement of the @Id
annotation gives the default access strategy.
When placed on a field, Hibernate will assume field-based access.
Place on the identifier getter, Hibernate will use property-based access.
You should pay attention to Java Beans specification in regard to naming properties to avoid issues such as Property name beginning with at least two uppercase characters has odd functionality in HQL! |
Embeddable types inherit the access strategy from their parent entities.
Field-based access
@Entity
public class Simple {
@Id
private Integer id;
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
}
When using field-based access, adding other entity-level methods is much more flexible because Hibernate won’t consider those part of the persistence state.
To exclude a field from being part of the entity persistent state, the field must be marked with the @Transient
annotation.
Another advantage of using field-based access is that some entity attributes can be hidden from outside the entity.
An example of such attribute is the entity |
Property-based access
@Entity
public class Simple {
private Integer id;
@Id
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
}
When using property-based access, Hibernate uses the accessors for both reading and writing the entity state.
Every other method that will be added to the entity (e.g. helper methods for synchronizing both ends of a bidirectional one-to-many association) will have to be marked with the @Transient
annotation.
Overriding the default access strategy
The default access strategy mechanism can be overridden with the JPA @Access
annotation.
In the following example, the @Version
attribute is accessed by its field and not by its getter, like the rest of entity attributes.
@Entity
public class Simple {
private Integer id;
@Version
@Access( AccessType.FIELD )
private Integer version;
@Id
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
}
Embeddable types and access strategy
Because embeddables are managed by their owning entities, the access strategy is therefore inherited from the entity too. This applies to both simple embeddable types as well as for collection of embeddables.
The embeddable types can overrule the default implicit access strategy (inherited from the owning entity). In the following example, the embeddable uses property-based access, no matter what access strategy the owning entity is choosing:
@Embeddable
@Access(AccessType.PROPERTY)
public static class Change {
private String path;
private String diff;
public Change() {}
@Column(name = "path", nullable = false)
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Column(name = "diff", nullable = false)
public String getDiff() {
return diff;
}
public void setDiff(String diff) {
this.diff = diff;
}
}
The owning entity can use field-based access, while the embeddable uses property-based access as it has chosen explicitly:
@Entity
public class Patch {
@Id
private Long id;
@Embedded
private Change change;
}
This works also for collection of embeddable types:
@Entity
public class Patch {
@Id
private Long id;
@ElementCollection
@CollectionTable(
name="patch_change",
joinColumns=@JoinColumn(name="patch_id")
)
@OrderColumn(name = "index_id")
private List<Change> changes = new ArrayList<>();
public List<Change> getChanges() {
return changes;
}
}