0

I have some questions regarding the @Access annotation of javax.persistence.

some background: I updated my hibernate version from 5.0.3.Final to 5.4.24.Final.

for some reason, after the upgrade, the app did not load because I had a problem with some of my entity classes (not all).

The common factor between those entities was that all of them were Triple inheritance.

example:

@MappedSuperclass
public abstract class BaseEntry {
    private Long id;

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "ID", insertable = false, updatable = false)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
} 


@MappedSuperclass
public class ManagedIncidentEntry extends BaseEntry {

private String type;

    @Column(name = "TYPE")
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

}



@Entity
@Table(name = "MANAGED_INCIDENTS")
public class ManagedIncidentRawInfoEntry extends ManagedIncidentEntry {
    
    private String additionalInfo;
   @Column(name = "ADDITIONAL_INFO")
    public String getAdditionalInfo() {
        return additionalInfo;
    }

    public void setAdditionalInfo(String additionalInfo) {
        this.additionalInfo = additionalInfo;
    }
}

after reviewing the user guide https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

I saw some example in the UG with @Access annotation and I play with the annotation , each time used a different value or placed it in different parts in the code and eventually the problem was fixed.

this in the middle class after the fix.

@MappedSuperclass
@Access( AccessType.FIELD )
public class ManagedIncidentEntry extends BaseEntry {

private String type;

  @Access( AccessType.PROPERTY )
    @Column(name = "TYPE")
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

}

Now I want to learn as much as I can about this annotation.

  1. why did I need to use it in the first place? meaning why the app worked without it on hibernate version 5.0.3.Final?

  2. what is the purpose of this annotation? I found this answer What is the purpose of AccessType.FIELD, AccessType.PROPERTY and @Access but I still don't understand the purpose. the db needs it to know from where to pull the value? from the field or from the getter?

  3. in the answer above they talked about the different between AccessType.FIELD and AccessType.PROPERTY

If you put them on the field - it will be AccessType.FIELD, if you put them on the getters - it will be AccessType.PROPERTY.

but when would I want to put it above a getter and when would I want to put it above a field?

  1. when would I want to put the the annotation above a specific field/getter and when would I want to put the annotation above the whole class

  2. are they specific kinds of java members that doesn't support the annotation? for example, when I played with the annotation, for some reason it didn't like it when I put the @Access( AccessType.FIELD ) above List

  3. why I needed both @Access( AccessType.FIELD ) above the class name and @Access( AccessType.PROPERTY ) above the getter? without the @Access( AccessType.FIELD ) didn't work (tomcat 10) and without the @Access( AccessType.PROPERTY ) the junit didn't work so I needed both

additional info - im using java 8 spring 5.3.25

Tal Levi
  • 363
  • 1
  • 6
  • 22
  • The DB doesn't need or use this - your JPA provider (hibernate) needs to know to look at either the fields or the properties within your entities to serialize that data into the database. Just as your application should decide and stick to accessing the fields in an object or (best practice) the accessors/properties to get data from an object. JPA has defaults, so if you put annotations on both properties and fields, only one set will be used, the others ignored - the access annotation allows you to specify at the class level, and to override it for certain fields/methods. – Chris Mar 01 '23 at 17:54
  • The answer you linked answers most of your questions too - "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.)". The access type defines how JPA will access that data to push it into the DB or your object, and accessor methods allow you to manipulate that as well, giving the DB data one view of the data that might be different from how you store it in the entity object. Like a phone number having country, area and other numbers, but it might be stored as a single string in the DB – Chris Mar 01 '23 at 19:13
  • so according to my understanding, (and correct me if I'm wrong) you need to use one of each not both... so why my code only worked when I used both? @Access( AccessType.FIELD ) above the class name and @Access( AccessType.PROPERTY ) above the getter – Tal Levi Mar 01 '23 at 21:25
  • When in doubt, read the specification: https://download.oracle.com/otndocs/jcp/persistence-2_1-fr-eval-spec/index.html You haven't provided enough info, but you are likely mixing access types in your entity inheritance graph. You should put all annotations on properties OR fields, not both. The first annotations JPA comes across in inheritance usually set the default access type for that graph - causing annotations on the 'other' type to get ignored. If you need to switch between propert/field access, that is when you need the @Access annotation(s). – Chris Mar 01 '23 at 21:38
  • which info is missing? – Tal Levi Mar 02 '23 at 08:08
  • The entities? You've shown partial views, and as this issue occurs if you mix and match annotations on fields and properties in a graph without specifying access types to tell it which to use for the entities- no one here is going to be able to find the needle in the haystack where your problem lies. – Chris Mar 02 '23 at 15:30

0 Answers0