Saturday, April 17, 2010

Identity Crisis: JPA @Id

Who am I?

Allow me to show you a simple JPA mapping,

@MappedSuperclass
public class Domain implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_SEQ")
private Integer id;

public Integer getId() {
return id;
}

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



Do you see the thorny issue here?

Look again.

Yes, you're right - the setter method!

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_SEQ")

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



In my view, the setter method should not be there at all as id property is marked as "sequence". How often do you invoke setId(Integer) method? I believe rarely or almost never.

A question emerges from the back of your mind - "But I need that for my unit test?!".

If you populate this property yourself, then there's something wrong with your unit test and I strongly suggest that you rethink the way you write your test code.

I admit I've done this before many times. You are not alone my friend.

"Who is it that can tell me who I am?"

2 comments:

  1. Interesting...

    I have often thought about why we publicly make all these getters & setters available... (long time ago back in java 1.2 I used to just make my class properties public and reference them that way! I know I know... how could I not encapsulate?!?! It was a long time ago).

    Anyway... I believe ORMs like Hibernate use the setter method when it constructs your object.

    So although the id is generated during construction and when you save it to your DB, it may need to be populated when the ORM retrieves your entity (I believe)...

    ReplyDelete
  2. Looks like Hib uses reflection on field level with annons...

    Following the tutorial...
    http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html

    This class uses standard JavaBean naming conventions for property getter and setter methods, as well as private visibility for the fields. Although this is the recommended design, it is not required. Hibernate can also access fields directly, the benefit of accessor methods is robustness for refactoring.

    ---

    Looks like you can do away with the setter afterall!

    Encapsulation can sometimes be overrated... but I guess it has to be applied appropriately.

    ReplyDelete