Friday, May 23, 2008

Entity Method Instances From hibernate.cfg.xml

Wouldn't it be cool if you could obtain an instance of a particular annotated method from a Hibernate entity by simply examining the hibernate.cfg.xml file? It's not as difficult as you may think.
The key to the whole process is knowing how to read the configuration file and manipulate what it returns. Let's examine some code that does just that. We'll examine all the classes in our config file and retrieve information on each of the methods annotated with @Id. We'll put this information in a map with the map's keys being the classes themselves and the values being Hibernate IdMetaData objects.

Map idMap = new HashMap();
1 Configuration config = new AnnotationConfiguration().configure();

2 for (Iterator iter = config.getClassMappings(); iter.hasNext();)
3 RootClass root = ((RootClass);

try {
4 Class clazz = root.getMappedClass();

5 Method idGetter = root.getIdentifierProperty()
6 Method idSetter = root.getIdentifierProperty()
7 Class type = idGetter.getReturnType();
8 IdMetaData md = new IdMetaData();
9 md.setIdGetter(idGetter);
10 md.setIdSetter(idSetter);
11 md.setType(type);
12 idMap.put(clazz, md);
13"mapping Id for " + clazz.getName());
catch (Exception e) {
throw new Error("unable to initialize annotation map");
Line 1 is the standard way to generate a Hibernate configuration instance. The Iterator of line 2 returns a Hibernate RootClass (line 3) for each of the defined classes in the config file. This class is the gateway to a lot of information.
root.getIdentifierProperty() in lines 5 and 6 returns a Hibernate Property object of the method marked with the @Id annotation. This allows access to the actual getter and setter methods. IdMetaData is a simple bean class that holds any information obtained from the RootClass object. Line 12 fills a HashMap with the class as the map key and the IdMetaData as the value. Once you know the trick you can programatically get at any information you wish to.
Developers read APIs, Engineers read the source code!

No comments: