Hibernate Annotations - Which is better, field or property access?

I prefer field access, because that way I'm not forced to provide getter/setter for each property.

A quick survey via Google suggests that field access is the majority (e.g., http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype).

I believe field access is the idiom recommended by Spring, but I can't find a reference to back that up.

There's a related SO question that tried to measure performance and came to the conclusion that there's "no difference".


There are arguments for both, but most of them stem from certain user requirements "what if you need to add logic for", or "xxxx breaks encapsulation". However, nobody has really commented on the theory, and given a properly reasoned argument.

What is Hibernate/JPA actually doing when it persists an object - well, it is persisting the STATE of the object. That means storing it in a way that it can be easily reproduced.

What is encapsulation? Encapsulations means encapsulating the data (or state) with an interface that the application/client can use to access the data safely - keeping it consistent and valid.

Think of this like MS Word. MS Word maintains a model of the document in memory - the documents STATE. It presents an interface that the user can use to modify the document - a set of buttons, tools, keyboard commands etc. However, when you choose to persist (Save) that document, it saves the internal state, not the set of keypresses and mouse clicks used to generate it.

Saving the internal state of the object DOES NOT break encapsulation - otherwise you don't really understand what encapsulation means, and why it exists. It is just like object serialisation really.

For this reason, IN MOST CASES, it is appropriate to persist the FIELDS and not the ACCESSORS. This means that an object can be accurately recreated from the database exactly the way it was stored. It should not need any validation, because this was done on the original when it was created, and before it was stored in the database (unless, God forbid, you are storing invalid data in the DB!!!!). Likewise, there should be no need to calculate values, as they were already calculated before the object was stored. The object should look just the way it did before it was saved. In fact, by adding additional stuff into the getters/setters you are actually increasing the risk that you will recreate something that is not an exact copy of the original.

Of course, this functionality was added for a reason. There may be some valid use cases for persisting the accessors, however, they will typically be rare. An example may be that you want to avoid persisting a calculated value, though you may want to ask the question why you don't calculate it on demand in the value's getter, or lazily initialise it in the getter. Personally I cannot think of any good use case, and none of the answers here really give a "Software Engineering" answer.


Here's a situation where you HAVE to use property accessors. Imagine you have a GENERIC abstract class with lots of implementation goodness to inherit into 8 concrete subclasses:

public abstract class Foo<T extends Bar> {

    T oneThing;
    T anotherThing;

    // getters and setters ommited for brevity

    // Lots and lots of implementation regarding oneThing and anotherThing here
 }

Now exactly how should you annotate this class? The answer is YOU CAN'T annotate it at all with either field or property access because you can't specify the target entity at this point. You HAVE to annotate the concrete implementations. But since the persisted properties are declared in this superclass, you MUST used property access in the subclasses.

Field access is not an option in an application with abstract generic super-classes.


I tend to prefer and to use property accessors:

  • I can add logic if the need arises (as mentioned in the accepted answer).
  • it allows me to call foo.getId() without initializing a proxy (important when using Hibernate, until HHH-3718 get resolved).

Drawback:

  • it makes the code less readable, you have for example to browse a whole class to see if there are @Transient around there.