Field Access vs Property Access in JPA and Hibernate

0
3186
  • 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;
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here