Reputation: 466
I'm working on some webservices, which I'm implementing with hibernate. The issue is that I need to access the names of the entity tables (say, those in @Table("Table_A")). The code is generated, so I cannot alter the entity classes themselves to give me what I need.
This is what I was doing so far:
public static
<T extends Entity<K>, K extends Serializable>
String getTableName(Class<T> objClass) {
Table table = objClass.getAnnotation(Table.class);
return (table != null)? table.name() : null;
}
However, after some research I discovered that reflection is not the best performance-wise, and since this method will be called a lot I'm looking for another way to go at it.
I'm trying to follow the advice given here: Performance of calling Method/Field.getAnnotation(Class) several times vs. Pre-caching this data in a Map.
This is what I came up with:
public final class EntityUtils {
private static HashMap<String, String> entityCache;
private EntityUtils() {
entityCache = new HashMap<String, String>();
}
public static
<T extends Entity<K>, K extends Serializable>
String getTableName_New(Class<T> objClass) {
String tableName = entityCache.get(objClass.getCanonicalName());
if (tableName == null) {
Table table = objClass.getAnnotation(Table.class);
if (table != null) {
tableName = table.name();
entityCache.put(objClass.getCanonicalName(), tableName);
}
}
return tableName;
}
}
However, I'm not sure about this. Is it a good idea to cache reflection data in a static map? Is there any alternative way to accomplish this?
Upvotes: 2
Views: 3719
Reputation: 298908
Ideally, I would use a Guava cache, with weak keys, that way you're not keeping any references to the class object in case you use some advanced ClassLoader magic.
LoadingCache<Class<?>, String> tableNames = CacheBuilder.newBuilder()
.weakKeys()
.build(
new CacheLoader<Class<?>, String>() {
public String load(Class<?> key) {
Table table = objClass.getAnnotation(Table.class);
return table == null ? key.getSimpleName() : table.name();
}
});
Usage:
String tablename = tableNames.get(yourClass);
See: Caches Explained
On the other hand: annotations are cached by the JDK also, so your previous approach is probably fine
Upvotes: 3