What Is the Purpose of Accesstype.Field, Accesstype.Property and @Access

What is the purpose of AccessType.FIELD, AccessType.PROPERTY and @Access

By default the access type is defined by the place where you put your identifier annotation (@Id). If you put it on the field - it will be AccessType.FIELD, if you put it on the getter - it will be AccessType.PROPERTY.

Sometimes you might want to annotate not fields but properties (e.g. because you want to have some arbitrary logic in the getter or because you prefer it that way.) In such situation you must define a getter and annotate it as AccessType.PROPERTY.

As far as I remember, if you specify either AccessType.FIELD or AccessType.PROPERTY on any of the entity fields / methods you must specify the default behaviour for the whole class. And that's why you need to have AccessType.FIELD on the class level (despite that AccessType.FIELD is the default value.)

Now, if you wouldn't have @Transient on the phnnumber field, the JPA would provide you with a 3 columns table:

  • id,
  • phnnumber,
  • getphnnumber.

That's because it would use AccessType.FIELD for all of the entity fields (id and phnnumber) and, at the same time, it'd use AccessType.PROPERTY for your getter (getPhnnumber()).

You'll end with phone number mapped twice in the database.

Therefore, the @Transient annotation is required - it means that the entity won't store the value of the field in the underlying storage but the value returned by your getter.

JPA: what is the default accessType FIELD or PROPERTY?

Official specification

http://download.oracle.com/otn-pub/jcp/persistence-2.0-fr-eval-oth-JSpec/persistence-2_0-final-spec.pdf

2.3.1 Default Access Type Page 23

By default, a single access type (field or property access) applies to an entity hierarchy. The default access type of an entity hierarchy is determined by the placement of mapping annotations on the attributes of the entity classes and mapped superclasses of the entity hierarchy that do not explicitly
specify an access type.

An access type is explicitly specified by means of the Access annotation [6]
, as described in section 2.3.2.

2.3.2
Explicit Access Type
An access type for an individual entity class, mapped superclass, or embeddable class can be specified for that class independent of the default
for the entity hierarchy by means of the Access annotation applied to the class. This explicit access type specification does not affect the access type of other entity classes or mapped superclasses in the entity hierarchy. The following rules apply:

When Access(FIELD) is applied to an entity class, mapped superclass, or embeddable class, mapping annotations may be placed on the instance variables of that class, and the persistence provider runtime accesses persistent state via the instance variables defined by the class. All non-transient instance variables that are not annotated with the Transient annotation are persistent.

When Access(FIELD) is applied to such a class, it is possible to
selectively designate individual attributes with
in the class for property access. To specify a
persistent property for access by the persistence provider runtime, that property must be desig-
nated
Access(PROPERTY)
.
[8]
The behavior is undefined if mapping annotations are placed
on any properties defined by the class for which
Access(PROPERTY) is not specified. Persistent state inherited from superclasses is accessed in accordance with the access types of
those superclasses.

Conclusion:
First annotation on field or getter determines access for whole entity.

When Access(PROPERTY) is used ...rules chaged

@Access(value=AccessType.FIELD)
@Entity(name="STUDENT")
public class Student {
... all mus be annotated on FIELD

}

Invalid Hibernate warning? '@Access(AccessType.PROPERTY) on a field has no effect'

@Access(AccessType.PROPERTY) is meant to be placed on a getter, like:

@Access(AccessType.PROPERTY)
@Column(length = 10, name = "user_type")
public String getUserType() {
return this.userType.getType();
}

public void setUserType(UserType userType) {
this.userType = userType;
}

protected void setUserType(String userType) {
userType = UserType.toUserType(userTypeS);
}

private String userTypeS; is not needed at all.

Hibernate Annotations - Which is better, field or property access?

I prefer accessors, since I can add some business logic to my accessors whenever I need.
Here's an example:

@Entity
public class Person {

@Column("nickName")
public String getNickName(){
if(this.name != null) return generateFunnyNick(this.name);
else return "John Doe";
}
}

Besides, if you throw another libs into the mix (like some JSON-converting lib or BeanMapper or Dozer or other bean mapping/cloning lib based on getter/setter properties) you'll have the guarantee that the lib is in sync with the persistence manager (both use the getter/setter).

Hibernate set property access strategy on whole Spring Boot application

I don't think such a property exists in Spring Boot by default.

However, you can create a parent class for all your entities to define @AccessType at the class level just once.

Documentation

http://download.oracle.com/otn-pub/jcp/persistence-2.0-fr-eval-oth-JSpec/persistence-2_0-final-spec.pdf

2.3.1 Default Access Type (Page 23)

By default, a single access type (field or property access) applies to
an entity hierarchy. The default access type of an entity hierarchy is
determined by the placement of mapping annotations on the attributes
of the entity classes and mapped superclasses of the entity hierarchy
that do not explicitly specify an access type.

Example

@MappedSuperclass
@Access(value=AccessType.FIELD)
public class Parent {
}

@Entity
public class Child extends Parent {
...
}


Related Topics



Leave a reply



Submit