- The JPA Specification allows access the properties of a class either directly through fields or indirectly through getter and setter methods.
- JPA introduced standard annotation to control this behaviour in JPA 2.0 (JSR-317).
- The default behaviour is, location of the mandatory id property of the POJO with @Id annotation in hibernate determines the access level of this domain object.
- For example @Id annotation located at the field level then that entity access behaviour is Field Access (OR) if @Id annotation located at the getter method entity access behaviour is Property Access. This is default behaviour.
- If access type is Property access JPA provider calls getter and setter methods runtime to load/store. For the Field access type JPA provider access fields directly, like how we can access fields within a class.
Technologies Used in following example :
- JPA 2.1
- Hibernate 5.2.6
- MySql 8.0
- Maven 3
- Spring Tool Suite (STS) 3.9.8
- Java 1.8
Default behavior – Field Access :
@Entity(name="STUDENT") public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "native") @GenericGenerator(name = "native", strategy = "native") @Column(name = "ID") private Long studentId; @Column(name = "FNAME") private String firstName; @Column(name = "LNAME") private String lastName; @Column(name = "CONTACT_NO") private String contactNo; public Long getStudentId() { return studentId; } public void setStudentId(Long studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getContactNo() { return contactNo; } public void setContactNo(String contactNo) { this.contactNo = contactNo; } }
Default behavior – Property Access :
@Entity(name="STUDENT") public class Student { private Long studentId; private String firstName; private String lastName; private String contactNo; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "native") @GenericGenerator(name = "native", strategy = "native") @Column(name = "ID") public Long getStudentId() { return studentId; } public void setStudentId(Long studentId) { this.studentId = studentId; } @Column(name = "FNAME") public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } @Column(name = "LNAME") public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Column(name = "CONTACT_NO") public String getContactNo() { return contactNo; } public void setContactNo(String contactNo) { this.contactNo = contactNo; } }
Overriding the default behaviour :
- JPA provides @Access annotation for overriding the default behavior, by using AccessType.FIELD and AccessType.PROPERTY. If you set @Access on the class/entity level, Hibernate accesses all properties of the class according to the selected strategy. You then set any other mapping annotations, including the @Id, on either fields or getter methods, respectively.
- You can also use the @Access annotation to override the access strategy of individ- ual properties.
- JPA supports Mixed Access also, it means you can locate annotations some at field level and some at property level.
/* if used @Access(value=AccessType.FIELD), all the annotation mapping should be at property level.*/ @Access(value=AccessType.FIELD) @Entity(name="STUDENT") public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ID") private Long studentId; @Column(name = "FNAME") private String firstName; @Column(name = "LNAME") private String lastName; @Column(name = "CONTACT_NO") private String contactNo; public Long getStudentId() { return studentId; } public void setStudentId(Long studentId) { this.studentId = studentId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getContactNo() { return contactNo; } public void setContactNo(String contactNo) { this.contactNo = contactNo; } }