views:

1277

answers:

2

I was curious if anyone had any hard numbers around the performance difference between annotating Entities using private fields instead of public getter methods. I've heard people say that fields are slower because they're called "through reflection" but then again so are the getter methods, no? Hibernate needs to set the accessibility of the field to true before it tries to read it which I can see having some slight overhead. However wouldn't that be done at the Class-level in the scope of a Session or perhaps only once when the Configuration is read and SessionFactory is built?

Just curious if this is a myth or if there's really truth to it; I personally find annotating the fields to be a bit more readable.

A: 

ok, I can't give numbers haha, but I would guess that accessing the fields through reflection wouldn't be a 'one time' thing. Each object has its own private members.

I honestly don't know much about reflection but the getter/setters should be straight forward. In fact you can try setting one of the methods to private and I think it won't work because it can't find the method it needs.

There are other issues like proxies that will affect getter methods though depending on how you load your entities.

This is all I see in the documentation:

The access attribute lets you control how Hibernate will access the property at runtime. By default, Hibernate will call the property get/set pair. If you specify access="field", Hibernate will bypass the get/set pair and access the field directly, using reflection. You may specify your own strategy for property access by naming a class that implements the interface org.hibernate.property.PropertyAccessor.

My guess is that reflection in general is going to be a higher cost though, but sorry.. no numbers :(

Arthur Thomas
The get/set methods need to be invoked through reflection also. There is no way at compile time that Hibernate can know which get/set pairs it will need to invoke on a class. My point about setting the accessibility is that it's done at the Class level on a java.lang.reflect.Field instance...
cliff.meyers
ahh yes, I guess that makes sense since it has to look up the actual names.
Arthur Thomas
+1  A: 

Loaded 5000 records into a simple 3 column table. Mapped two classes to that table, one using annotated private fields and another using annotated public getters. Ran 30 runs of Spring's HibernateTemplate.loadAll() followed by a HibernateTemplate.clear() to purge the Session cache. Results in ms below...

methods total: 6510, average: 217 fields total: 6586, average: 219

I should probably take another stab at it after adding more properties to each class but right now the difference doesn't appear to be statistically significant.

cliff.meyers
5000 records isn't statistically significant. Can you try it with a more complex entity structure (which would need joins), and with something like 100x the number of records? You will always have fast performance with small data sets.
Justin Standard