Chapter 7. Controlling POJO code generation

When using the <hbm2java> tag or the Eclipse plugin to generate POJO Java code you have the ability to control certain aspects of the code generation process. This is primarily done with the <meta> tag in the mapping files. The following section describes the possible <meta> tags and their use.

7.1. The <meta> attribute

The <meta> tag is a simple way of annotating the hbm.xml file with information, so tools have a natural place to store and read information that is not directly related to the Hibernate core.

As an example, you can use the <meta> tag to tell the <hbm2java> tag to only generate "protected" setters, have classes always implement a certain set of interfaces, have them extend a certain base class and more.

The following example shows how to use various <meta> attributes and the resulting Java code.

What does that mean? As an example if you want to have all your classes implement IAuditable then you just add <meta attribute="implements">IAuditable</meta> in the top of the hbm.xml file, just after <hibernate-mapping>. Now all classes defined in that hbm.xml file will implement IAuditable.

Note:

This applies to all<meta>-tags. Thus it can also be used to specify that all fields should be declare protected, instead of the default private. This is done by adding <meta attribute="scope-field">protected</meta> just under the <class> tag, and all fields of that class will be protected.

To avoid having a <meta> tag inherited then you can specify inherit = "false" for the attribute. For example <meta attribute = "scope-class" inherit = "false">public abstract</meta> will restrict the "class-scope" to the current class, not the subclasses.

7.1.1. Recommendations

The following are some good practices to employ when using <meta> attributes.

7.1.1.1. Dangers of a class level use-in-string and use-in-equals meta attributes when using bi-directional associations

In the following example we have two entities with a bi-directional association between them and define the use-in-string and use-in-equals meta attributes at the class scope level the meta attributes:

In this situation the <hbm2java> tag will assume you want to include all properties and collections in the toString() and equals() methods. This can result in infinite recursive calls.

To remedy this you have to decide which side of the association will include the other part (if at all) in the toString() and equals() methods. Therefore it is not a good practice to define these meta attributes at the class scope, unless you are defining a class without bi-directional associations.

Instead it is recommended that the meta attributes are defined at the property level, like so:

Only attributes with business meaning (e.g. the name, social security number, etc, but no generated id's) should be referenced when calculating the return value for the equal() and hashCode() methods.

This is important because Java's hashbased collections, such as java.util.Set, rely on equals() and hashcode() being correct and not changing for objects in the set; this can be a problem if the id gets assigned for an object after you inserted it into a set.

Therefore automatically configuration of the generation of equals() and hashCode() methods specifying the <meta> attribute use-in-equals at class scope level could be a dangerous decision that could produce unexpected side-effects.

On www.hibernate.org you can find more in-depth explanation on the subject of equals() and hashcode() methods.

7.1.2. Advanced <meta> attribute examples

This section shows an example for using meta attributes (including user specific attributes) together with the code generation features in Hibernate Tools™.

The example shown below automatically inserts some pre and post conditions into the getter and setter methods of the generated POJO.

7.1.2.1. Generate pre/post-conditions for methods

With <meta attribute="class-code"> you can add additional methods on a given class. However, such <meta> attributes can not be used at a property scope level and Hibernate Tools does not provide such <meta> attributes.

A possible solution for this is to modify the Freemarker templates responsible for generating the POJOs. If you look inside the hibernate-tools.jar archive, you can find the template pojo/PojoPropertyAccessor.ftl.

As its name indicates, this file is used to generate property accessors for POJOs.

Extract the PojoPropertyAccessor.ftl file into a local folder e.g. ${hbm.template.path}, respecting the whole path, for example: ${hbm.template.path}/pojo/PojoPropertyAccessor.ftl.

Note:

I) To escape the & symbol we put &amp;. You could use <![CDATA[]]> instead.

II) Note that we are referring to firstName directly and this is the parameter name not the actual field name. If you want to refer the field you have to use this.firstName instead.

Finally we have to generate the Person.java class. For this we can use either Eclipse or Ant, as long as you remember to set or fill in the templatepath setting. For Ant we configure the <hibernatetool> task via the templatepath attribute as in: