Why should anybody put annotations on the getters or setters when using JPA to map the classes?

27,867

Solution 1

Putting annotations on methods forces JPA to access properties via methods. It makes sense when internal state of your object differs from the database schema:

@Entity
public class Employee {
    private String firstName;
    private String lastName;

    @Column(name = "EMP_NAME") // Due to legacy database schema
    public String getName() {
        return fisrtName + " " + lastName;
    }

    public void setName(String name) {
        ...
    }

    ... Getters and setters for firstName and lastName with @Transient ...
}

In JPA 2.0 you can specify access type at fine-grained level with @Access:

@Entity @Access(AccessType.FIELD)
public class Employee {
    @Access(AccessType.PROPERTY) @Column(name = "EMP_NAME")
    public String getName() { ... }
    ... other properties have field access ...
}

Solution 2

Why should anybody put annotations on the getters or setters when using JPA to map the classes?

As already mentioned, using property access allows to add logic in the getter, if the need arises.

But since the question is tagged , I'll mention another (huge) benefit: property access allows you to call foo.getId() without initializing a proxy. You cannot get the same behavior when using field access. Emmanuel Bernard explains this limitation of field access as follows:

That is unfortunate but expected. That's one of the limitations of field level access. Basically we have no way to know that getId() indeed only go and access the id field. So we need to load the entire object to be safe.

So yes, using property access makes the code harder to read, you have for example to browse a whole class to see if there are any @Transient around there. But for me, the benefit (at least with ) outweighs this disadvantage by far.

Related questions

References

Solution 3

The answers given are correct. Annotating methods instead of properties gives you:

  1. The right to use getId(), if it's marked as the @Id value, to get a foreign key value from a proxy object without actually loading it from the DB.

  2. You can create getters/setters that update internal object state that is not in the database. I've used this when retrieving compressed state from the DB that I want to decompress within the object into a more usable internal member datum. The setters and getters set and get the compressed state, and the DB and Hibernate don't "know" about the uncompressed internal member.

There is one drawback I've hit:

A. Your setters have to be pretty simple. Hibernate expects them to do what would be accomplished by direct assignment to a member datum. A "setCategory" method that not only sets a category, but also updates the relevant Category object to show the relationship, may get you into trouble.

Share:
27,867
Kawu
Author by

Kawu

Updated on September 23, 2020

Comments

  • Kawu
    Kawu over 3 years

    Subject says it all... I see no advantage of people declaring annotations on the getters and/or setters so far. For me this only has the disadvantage of spreading the annotations over the class, which can make the class more unreadable.

    Putting the annotations on the fields clearly reduces the amount of code to post when needing help. This is just a tiny advantage though. But putting annotations on methods would serve no purpose to me.

  • Jadiel de Armas
    Jadiel de Armas over 9 years
    I think that Annotations on setters are not supported because it is more difficult to determine the class type of the field using reflection for a setter. For a getter, all you have to do is to check the return type of the method. But for a setter, what do you do if you are passing multiple parameters to it?