0% found this document useful (0 votes)
97 views6 pages

Access Strategies in JPA and Hibernate

The document discusses access strategies in JPA and Hibernate. There are two access strategies: field-based access and property-based access. By default, the strategy is determined by whether the primary key is annotated on the field or getter method. The strategies can be overridden using the @Access annotation. Field-based access is recommended for reasons such as better readability, omitting unnecessary getter/setters, flexible getter/setter implementation, avoiding the need for the @Transient annotation, and avoiding bugs when working with proxies.

Uploaded by

Adolf
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
97 views6 pages

Access Strategies in JPA and Hibernate

The document discusses access strategies in JPA and Hibernate. There are two access strategies: field-based access and property-based access. By default, the strategy is determined by whether the primary key is annotated on the field or getter method. The strategies can be overridden using the @Access annotation. Field-based access is recommended for reasons such as better readability, omitting unnecessary getter/setters, flexible getter/setter implementation, avoiding the need for the @Transient annotation, and avoiding bugs when working with proxies.

Uploaded by

Adolf
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Access Strategies in JPA and Hibernate

The access strategy defines how your JPA implementation, e.g.,


Hibernate or EclipseLink, access your entity attributes. You can
choose between field-based access and property-based access:
 If you use field-based access, your JPA implementation uses
reflection to read or write your entity attributes directly. It also
expects that you place your mapping annotations on your entity
attributes.
 If you use property-based access, you need to annotate the
getter methods of your entity attributes with the required
mapping annotations. Your JPA implementation then calls the
getter and setter methods to access your entity attributes.

How to specify the access strategy


Default configuration
By default, you specify the access strategy implicitly by annotating
your primary key attribute or its getter method with an @Id
annotation. If you annotate the attribute itself, Hibernate uses field-
based access.

@Entity
public class Review {

@Id
protected Long id;


}

And if you annotate a getter method with the @Id annotation,


Hibernate uses property-based access to set and read the attributes
of this entity.

www.thoughts-on-java.org
Access Strategies in JPA and Hibernate
@Entity
public class Review {

@Id
public Long getId() {
return id;
}


}

Override the default access strategy


If you want to mix both access strategies within one entity or a
hierarchy of entities, you need to override the default strategy with
an @Access annotation. Otherwise, the JPA specification defines the
behavior as undefined.
@Entity
public class Review {

@Version
@Access(AccessType.FIELD)
private int version;

@Id
public Long getId() {
return id;
}

}

www.thoughts-on-java.org
Access Strategies in JPA and Hibernate
5 reasons why you should use field-based access
As explained earlier, you most often specify your access strategy by
annotating the attributes or getter methods of your entity. But which
strategy should you choose? Does it make a real difference?
Yes, it does make a difference. I always recommend using field-based
access. Here are 5 reasons why field-based access is the better
access strategy.

Reason 1: Better readability of your code


If you use field-based access, you annotate your entity attributes
with your mapping annotations. By placing the definition of all entity
attributes at the top of your class, you get a relatively compact view
of all attributes and their mappings.

Reason 2: Omit getter or setter methods that shouldn’t be called by your


application
Another advantage of field-based access is that your persistence
provider, e.g., Hibernate or EclipseLink, doesn’t use the getter and
setter methods of your entity attributes. That means that you don’t
need to provide any method that shouldn’t be used by your business
code. This is most often the case for setter methods of generated
primary key attributes or version columns. Your persistence provider
manages the values of these attributes, and you should not set them
programmatically.

You can also provide utility methods that enable you to add or
remove elements from a to-many association and prevent direct
access to the underlying List or Set. This makes the implementation
of your business code more comfortable and is a general best
practice for bi-directional many-to-many associations.

www.thoughts-on-java.org
Access Strategies in JPA and Hibernate
@Entity
public class Book {

@ManyToMany
Set<Author> authors;

public void addAuthor(Author a) {


this.authors.add(a);
a.getBooks.add(this);
}

public void removeAuthor(Author a) {


this.authors.remove(a);
a.getBooks().remove(this);
}


}

Reason 3: Flexible implementation of getter and setter methods


Because your persistence provider doesn’t call the getter and setter
methods, they are not forced to fulfill any external requirements. You
can implement these methods in any way you want. That enables you
to implement business-specific validation rules, to trigger additional
business logic or to convert the entity attribute into a different data
type.
I use that in the following example to wrap an optional association in
a Java Optional. Even so, JPA and Hibernate don’t support Optional as
an attribute type, field-based access enables you to use it as the
return type of a getter method.

www.thoughts-on-java.org
Access Strategies in JPA and Hibernate
@Entity
public class Book {

@ManyToOne
Publisher publisher;

public void setPublisher(Publisher p) {


this.publisher = p;
}

public Optional<Publisher> getPublisher() {


return Optional<Publisher>.ofNullable(this.publisher);
}


}

Reason 4: No need to mark utility methods as @Transient


Another benefit of the field-based access strategy is that you don’t
need to annotate your utility methods with @Transient. This
annotation tells your persistence provider that a method or attribute
is not part of the entity persistent state. And because with field-type
access the persistent state gets defined by the attributes of your
entity, your JPA implementation ignores all methods of your entity.

Reason 5: Avoid bugs when working with proxies


Hibernate uses proxies for lazily fetched to-one associations so that
it can control the initialization of these associations. That approach
works fine in almost all situations. But it introduces a dangerous
pitfall if you use property-based access.
If you use property-based access, Hibernate initializes the attributes
of the proxy object when you call the getter method. That’s always

www.thoughts-on-java.org
Access Strategies in JPA and Hibernate
the case if you use the proxy object in your business code. But quite a
lot of equals and hashCode implementations access the attributes
directly. If this is the first time you access any of the proxy attributes,
these attributes are still uninitialized.
@Entity
public class Book {

@NaturalId
String isbn;

...

@Override
public int hashCode() {
return Objects.hashCode(isbn);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
return Objects.equals(isbn, other.isbn);
}
}

You can easily avoid this pitfall by using the field-based access
strategy.

www.thoughts-on-java.org

You might also like