Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 241
Kawu Avatar asked Nov 15 '10 19:11

Kawu


People also ask

What is the role of annotations in JPA?

JPA annotations are used in mapping java objects to the database tables, columns etc. Hibernate is the most popular implement of JPA specification and provides some additional annotations.

What is the purpose of using getters and setters?

Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.

Which annotation will you use to define getter and setter methods depending on the fields?

Overview. You can annotate any field with @Getter and/or @Setter , to let lombok generate the default getter/setter automatically. A default getter simply returns the field, and is named getFoo if the field is called foo (or isFoo if the field's type is boolean ).

Why we are using JPA annotation instead of Hibernate?

You use hibernate as implementation of JPA API. You should be able to change hibernate with another implementation (like EclipseLink) without changing in the code. This is why you should only use JPA annotations.


3 Answers

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 ...
}
like image 57
axtavt Avatar answered Oct 14 '22 16:10

axtavt


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 hibernate, 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 hibernate) outweighs this disadvantage by far.

Related questions

  • Hibernate Annotations - Which is better, field or property access?
  • Hibernate generating SQL queries when accessing associated entity's id

References

  • Proxy loaded on getId-call when using annotations on fields
  • proxy getId => why sql is generated !
  • HHH-3718
like image 28
Pascal Thivent Avatar answered Oct 14 '22 15:10

Pascal Thivent


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.

like image 25
Clint Avatar answered Oct 14 '22 16:10

Clint