JPA – Field vs Property vs Mixed Access Modes

In JPA, mapping information of an entity must be accessible to the ORM provider at runtime, so that when it is writing the data to storage, mapping information can be obtained from the entity instance. Similarly, when the entity state is loaded from the storage, the provider runtime must be able to map the data into a new entity instance.

There are generally two ways to provide this information to ORM providers i.e. @Access(AccessType.FIELD) and @Access(AccessType.PROPERTY). But we can use mixed mode as well in some cases.

Let’s learn about them in this tutorial.

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

1. Field Access Mode

To declare field access mode, explicitly annotate the entity with "@Access(AccessType.FIELD)“. Otherwise annotating the fields of the entity will cause the provider to use field access to get and set the state of the entity.

@Entity
@Access(AccessType.FIELD) //Use this to mention the mode explicitly
public class Employee
{
    @Id private long id;
}
  • Please note that getter and setter methods might or might not be present, but if they are present, they are ignored by the provider.
  • All fields must be declared as either protected, package, or private.
  • Public fields are disallowed because it would open up the state fields to access by any unprotected class in the JVM.

If getter and setter methods are ignored then can we really skip them from entities having field access mode?

NO, because there are other classes in the application that need to access that data fields, and access should always be given using public methods (though not necessarily getters and setters). That’s why, for convenience, we create getter and setter methods.

2. Property Access Mode

To declare property access mode, explicitly annotate the entity with “@Access(AccessType.PROPERTY)“, or mapping annotations for a property must be on the getter method.

@Entity
public class Employee
{
    private long id;
    private long income;

    @Id
    public long getId() { return id; }
    public void setId(long id) { this.id= id; }

    public long getSalary() { return income; }
    public void setSalary(long salary) { this.income = salary; }
}
  • When property access mode is used, the same contract as for JavaBeans applies, and there must be getter and setter methods for the persistent properties.
  • The type of property is determined by the return type of the getter method and must be the same as the type of the single parameter passed into the setter method.
  • Both methods must be either public or protected visibility. The mapping annotations for a property must be on the getter method.

In the above example, the Employee class has an @Id annotation on the getId() getter method so the provider will use property access to get and set the state of the entity.

Note that the salary property (will be mapped to the SALARY column in database) is backed by the income field, which does not share the same name. This goes unnoticed by the provider because by specifying property access, we are telling the provider to ignore the entity fields and use only the getter and setter methods for naming.

3. Mixed Access Mode

Though you will not require to mix modes in most of the scenarios, it is possible and useful in some cases.

For example, when an entity subclass is added to an existing hierarchy that uses a different access type.

Adding an @Access annotation with a specified access mode on the subclass entity (or even field) will cause the default access type to be overridden for that entity subclass.

Happy Learning !!

Leave a Reply

1 Comment
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial