Why hibernate?
If your application ( like this one ) needs to keep some data in relational database,
first idea would to work with database directly (using standard jdbc framework). There are
drivers for almost any RDBMS around and it works. But this is not really convenient. After
all, java is object oriented language, but jdbc returns just fields - so you have to
populate objects yourself. This means a lot of work to develop and debug. And if there are
complex relations you are almost lost. You definitely would need some magic to get your objects
out of database and save them there. Hibernate
does the magic.
Persistent data
Let's start with our data objects. To implement link rotation we will need
a some java objects which describe our website, websites we exchange links to
and their relations.
You are welcome to check out complete source code from repository and play around
with it:
svn co https://jtec.svn.sourceforge.net/svnroot/jtec/jtec-linkomatic/trunk jtec
This is a maven-2 project with complete unit tests, sou you can easy see how it is supposed
to work.
Those beans and helper objects defining website relations can be found in source package
de.jtec.linkomatic.beans
Hibernate needs information, how to map objects to database tables and how to
manage their relations. This information is contained in metadata ( XML-files ):
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="pool" name="de.jtec.linkomatic.beans.Pool">
<id unsaved-value="null" name="id">
<generator class="native"/>
</id>
<bag inverse="true" cascade="none" where="active=1" mutable="false" lazy="true" name="activeLinks">
<key column="pool"/>
<one-to-many class="de.jtec.linkomatic.beans.Rotation"/>
</bag>
<property name="amountToDispatch"/>
<bag inverse="true" cascade="none" where="approved=0" mutable="false" lazy="true" name="disabledLinks">
<key column="pool"/>
<one-to-many class="de.jtec.linkomatic.beans.Rotation"/>
</bag>
<bag inverse="true" cascade="none" where="approved=1 and active=0 " mutable="false" lazy="true" name="enabledLinks">
<key column="pool"/>
<one-to-many class="de.jtec.linkomatic.beans.Rotation"/>
</bag>
<property name="format" column="kind"/>
<component name="link">
<property name="language"/>
<property name="description"/>
<property name="destination"/>
<property name="title"/>
</component>
<bag cascade="delete" lazy="true" name="links">
<key column="pool"/>
<one-to-many class="de.jtec.linkomatic.beans.Rotation"/>
</bag>
<property name="owner" update="false" insert="true"/>
<bag inverse="true" cascade="none" access="field" order-by="credits desc" where="active=1 and credits > 0" mutable="false" lazy="true" name="dispatchLinks">
<key column="pool"/>
<one-to-many class="de.jtec.linkomatic.beans.Rotation"/>
</bag>
<query name="all"><![CDATA[from de.jtec.linkomatic.beans.Pool as p]]></query>
<query name="owned"><![CDATA[from de.jtec.linkomatic.beans.Pool as p where p.owner = :owner]]></query>
</class>
</hibernate-mapping>
Looks complex? It is complex. Even for those small simple java beans. And it must be
keept in synch with original java code. But good news are, there is
XDoclet to do this work for us. Look into java source files -
there are funny metadata eveywhere in comments. XDoclet reads those javadoc tags
and creates xml configuration file for hibernate.
To see how it works, start maven 2 in directory where you checked out source code:
mvn generate-sources
If you are curious, you may already have looked at implementation of manager classes
(HibernateLinkomatic)
You will notice, that ony code contained there ( and superclass ) is dealing with loading, saving and deleting of
a data, and not with management or configuration of hibernate. If you are really curious, you will
wind no sich code in whole source (well, test cases contain some management code, but they are not
used in rest of project). You may be wondering, how this is ever going to work?
The answer is - DependencyInjection.