What just happened?
Ant found all files in our source tree ending in
.hbm.xml (just one, so far) and fed it to the
Hibernate code generator, which analyzed it, and wrote a Java class
meeting the specifications we provided for the Track mapping.
NOTE
That can save a lot of time and fairly repetitive activity. I could get used to it.
You may find it worthwhile to compare the generated Java source with
the mapping specification from which it arose (Example 2-1). The source starts out with the proper
package declaration, which is easy for hbm2java
to figure out from the fully qualified class name required in the
mapping file. There are a couple of imports to make the source more
readable. The three potentially unfamiliar entries (lines 5-7) are utilities
from the Jakarta
Commons project that help in the creation of correctly implemented
and useful toString( ),
equals( ), and hashCode( )
methods.
The class-level JavaDoc at line 10 should
look familiar, since it comes right from the
"class-description"
meta tag in our mapping document. The field
declarations are derived from the id (line 17) and
property (lines 20-32) tags defined in
the mapping. The Java types used are derived from the property types
in the mapping document. We'll delve into the full
set of value types supported by Hibernate later on. For now, the
relationship between the types in the mapping document and the Java
types used in the generated code should be fairly clear.
One curious detail is that an Integer wrapper has
been used for id, while volume
is declared as a simple, unwrapped short. Why the
difference? It relates to the fact that the ID/key property has many
important roles to play in the O/R mapping process
(which is why it gets a special XML tag in the mapping document,
rather than being just another property). Although
we left it out in our specification, one of the choices you need to
make when setting up an ID is to pick a special value to indicate
that a particular instance has not yet been saved into the database.
Leaving out this unsaved-value attribute, as we
did, tells Hibernate to use its default interpretation, which is that
unsaved values are indicated by an ID of null.
Since native int values can't be
null, they must be wrapped in a
java.lang.Integer, and Hibernate took care of this
for us.
When it comes to the volume property, Hibernate
has no special need or use for it, so it trusts us to know what
we're doing. If we want to be able to store
null values for volume, perhaps
to indicate "no change," we need to
explicitly use java.lang.Short rather than
short in our mapping document. (Had we not been
sneakily pointing out this difference, our example would be better
off explicitly using java.lang.Integer in our ID
mapping too, just for clarity.)
Another thing you might notice about these field declarations is
that their JavaDoc is quite generic—you may be wondering what
happened to the "field-description"
meta tags we put in the mapping document for
playTime, added and
volume. It turns out they appear only later, in
the JavaDoc for the getter methods. They are not used in the setters,
the actual field declarations, nor as @param
entries for the constructor. As an avid user of a code-completing
Java editor, I count on pop-up JavaDoc as I fill in arguments to
method calls, so I'm a little disappointed by this
limitation. Of course, since this is an open source project, any of
us can get involved and propose or undertake this simple fix. Indeed,
you may find this already remedied by the time you read this book.
Once robust field and parameter documentation is in place,
I'd definitely advocate always providing a brief but
accurate field-description entry for your properties.
NOTE
I know, I'm a perfectionist. I only
bother to pick nits because I think Hibernate is so
useful!
After the field declarations come a trio of
constructors. The first (line 35) establishes values for all properties, the
second (line 44) allows instantiation
without any arguments (this is required if you want the class to be
usable as a bean, such as on a Java Server Page, a very common use
for data classes like this), and the last (line 48) fills in just the values
we've indicated must not be null.
Notice that none of the constructors set the value of
id; this is the responsibility of Hibernate when
we get the object out of the database, or insert it for the first
time.
Consistent with that, the setId( ) method on line
57 is protected, as
requested in our id mapping. The rest of the
getters and setters are not surprising; this is all pretty much
boilerplate code (which we've all written too many
times), which is why it's so nice to be able to have
the Hibernate extensions generate it for us.
WARNING
If you want to use Hibernate's generated code as a
starting point and then add some business logic or other features to
the generated class, be aware that all your changes will be silently
discarded the next time you run the code generator. In such a project
you will want to be sure the hand-tweaked classes are not regenerated
by any Ant build target.
Even though we're having Hibernate generate our data
classes in this example, it's important to point out
that the getters and setters it creates are more than a nice touch.
You need to put these in your persistent classes
for any properties you want to persist, since
Hibernate's fundamental persistence architecture is
based on reflective access to JavaBeans©-style
properties. They don't need to be
public if you don't want them to;
Hibernate has ways of getting at even properties declared
protected or private, but they
do need accessor methods. Think of it as enforcing good object
design; the Hibernate team wants to keep the implementation details
of actual instance variables cleanly separated from the
persistence mechanism.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|