21

I am currently learning Hibernate and the Java Persistence API.

I have an @Entity class, and need to apply annotations to the various fields. I have included in the code below all three places where they could go.

Should I apply them to the field itself, the getter or the setter? And what is the semantic difference, if any, between these three options.

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;

@Entity
@Table(name = "song")
public class Song { 
    // Annotations should only be applied to one of the below

    @Id 
    @Column(name="id", unique=true, nullable=false)
    private int    id;

    @Id
    @Column(name="id", unique=true, nullable=false)
    public int getId() {
        return id;
    }

    @Id
    @Column(name="id", unique=true, nullable=false)
    public void setId(int id) {
        this.id = id;
    }
}
James McGuigan
  • 7,542
  • 4
  • 26
  • 29
  • Possible duplicate http://stackoverflow.com/questions/4188048/why-should-anybody-put-annotations-on-the-getters-or-setters-when-using-jpa-to-m – Mairbek Khadikov Jan 22 '12 at 22:06
  • 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? – Jadiel de Armas Feb 02 '15 at 19:54

2 Answers2

35

You have to choose between field and getter. Annotations on setters are not supported. And all the annotations should be on fields, or they should all be on getters: you can't mix both approaches (except if you use the @AccessType annotation).

Regarding which one is preferrale, the answer is: it depends. I prefer field access, but YMMV, and there are situations where property access is preferrable. See Hibernate Annotations - Which is better, field or property access?.

Community
  • 1
  • 1
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    Also discovered that you can use it to getId() without fetching entire object http://stackoverflow.com/questions/2593722/hibernate-one-to-one-getid-without-fetching-entire-object/3238182#3238182 – James McGuigan Jan 22 '12 at 22:17
  • 1
    From: http://java.dzone.com/articles/jpa-implementation-patterns-7 Lazy loading in Hibernate - Hibernate's lazy loading implementation always initializes a lazy proxy when any method on that proxy is invoked. The only exception to this is the method annotated with the @Id annotation when you use property access. But when you use field access there is no such method and Hibernate initializes the proxy even when invoking the method that returns the identity of the entity. – James McGuigan Jan 22 '12 at 22:51
4

You have to put annotations only for field or only for getter

@Id 
@Column(name="id", unique=true, nullable=false)
private int    id;

public int getId() {
    return id;
}

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

or

private int    id;

@Id 
@Column(name="id", unique=true, nullable=false)
public int getId() {
    return id;
}

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

And for all fields/properties in same way. All annotations for fields or all annotations for getter

alexey28
  • 217
  • 2
  • 2