| Sign In/My Account | View Cart |
Hibernate Class Generation Using hbm2java
Pages: 1, 2, 3, 4, 5, 6
class-code Meta
AttributeFor simple methods, you can use the class-code meta
attribute to specify additional Java code from within the Hibernate
mapping file. For example, suppose we want a bidirectional
relation between a country and its airports. Whenever we add an
airport to a Country object, we want to be sure to set the
reciprocal country attribute in the Airport object. We can
do this as follows:
<class name="Country" table="COUNTRY" dynamic-update="true">
<meta attribute="implement-equals">true</meta>
<meta attribute="class-code">
<![CDATA[
/**
* Add an airport to this country
*/
public void addAirport(Airport airport) {
airport.setCountry(this);
if (airports == null) {
airports = new java.util.HashSet();
}
airports.add(airport);
}
]]>
</meta>
<id name="id" type="long" unsaved-value="null" >
<column name="cn_id" not-null="true"/>
<generator class="increment"/>
</id>
<property column="cn_code" name="code" type="string"/>
<property column="cn_name" name="name" type="string"/>
<set name="airports" >
<key column="cn_id"/>
<one-to-many class="Airport"/>
</set>
</class>
This approach is not particularly satisfying, except for very small
methods: writing Java code in XML files tends to be error-prone
and difficult to maintain.
Sometimes the business logic (especially if it involves aggregations, sums, totals, and so on) may be more naturally defined by an SQL expression:
<property name="orderTotal" type="java.lang.Double"
formula="(select sum(item.amount)
from item
where item.order_id = order_id)" />
This is an elegant solution in many cases. However, you should be aware that this query will be executed every time the object is loaded from the database, so it may penalize performance.
You can also use the generated-class meta attribute to
define a base class, which will be generated by
hbm2java, leaving you free to place your business
logic in a subclass of this generated class. For example, using
this technique for the Country class could be done as
follows:
<class name="Country" table="COUNTRY" dynamic-update="true">
<meta attribute="implement-equals">true</meta>
<meta attribute="generated-class">CountryBase</meta>
<meta attribute="scope-field">protected</meta>
<id name="id" type="long" unsaved-value="null" >
<column name="cn_id" not-null="true"/>
<generator class="increment"/>
</id>
<property column="cn_code" name="code" type="string"/>
<property column="cn_name" name="name" type="string"/>
<set name="airports" >
<key column="cn_id"/>
<one-to-many class="Airport"/>
</set>
</class>
hbm2java will generate the CountryBase
class, containing all the attributes, getters, setters, etc.
described by the mapping file. Then you are free to place your
business logic in the derived class called Country,
which will be used and instantiated by Hibernate; for example:
public class Country extends CountryBase {
/**
* Add an airport to this country
*/
public void addAirport(Airport airport) {
airport.setCountry(this);
if (getAirports() == null) {
setAirports(new java.util.HashSet());
}
getAirports().add(airport);
}
}
For more complex business logic, you may also want to use one of the following techniques:
This article describes one approach we used to manage Hibernate mappings, which worked well in our particular circumstances. There are, of course, many others. Maybe this article will provide some ideas for your projects, but whatever you do, use whatever suits your project best!
John Ferguson Smart is a freelance consultant specializing in Enterprise Java, Web Development, and Open Source technologies, currently based in Wellington, New Zealand.
Return to ONJava.com.
Showing messages 1 through 4 of 4.