16 April 2005

Aufwärmphase mit Hibernate

Default Konstruktoren machen es aus

Hibernate arbeitet mit sogenannten POJOs (Plain Old Java Objects) und zu diesen Objekten muss sinngemäss stets ein Default Konstruktor zur Verfügung stehen. Ansonsten reagiert Hibernate nicht so erfreut auf die Proxyklasse.

Data Description Language aus Mapping Dateien erstellen

Mit Hibernate können Applikationen datenbankunabhängig entwickelt werden. Dies ist vor allem sehr hilfreich, wenn man keine Administratorenrechte auf der Kundendatenbank hat oder mehrere Entwickler im Minutentakt ihre Testskripts gegen eine Datenbank ausführen und sich einander somit stören, da die Testresultate verfälscht werden.

Die freie Java Datenbank Hypersonic und Hibernate bieten sich hier als kleine aber mächtige Werkzeuge an, um dieses alltägliche Problem zu beheben.

Grundlage für das Beispiel bildet das folgende Hibernate Mapping File.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping package="ch.silvio.hibernate">
<class name="FileNetUser" table="tbl_filenet_user">
<id
column="fn_id"
name="Id"
type="integer"
>
<generator class="native" />
</id>
<property
column="fn_usr"
length="30"
name="Username"
not-null="true"
type="string"
/>
<property
column="fn_pwd"
length="30"
name="Password"
not-null="false"
type="string"
/>
</class>
</hibernate-mapping>

Diese einfache Enität beinhaltet als Attribute einen numerischen Schlüssel und jeweils eine Zeichenkette für Benutzername und Passwort. Mittels einem kleinen Java Programm und der Hibernate API lässt sich aus dieser Mapping Datei sowohl eine Java Klasse als auch ein SQL Skript (DDL) für eine von Hibernate unterstützten Datenbanken erstellen.

public class Hypersonic
{
//....
static
{
Configuration config = new Configuration();
config.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
config.setProperty("hibernate.connection.driver_class","org.hsqldb.jdbcDriver");
config.setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test");
config.setProperty("hibernate.connection.username", "sa");
config.setProperty("hibernate.connection.password", "");
config.setProperty("hibernate.connection.pool_size", "1");
config.setProperty("hibernate.connection.autocommit", "true");
config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider");
config.setProperty("hibernate.hbm2ddl.auto", "create-drop");
config.setProperty("hibernate.show_sql", "true");


config.addClass(FileNetUser.class);
factory = config.buildSessionFactory();
}
//...
}

Im vorherigen Codeausschnitt wird eine Hibernate Configuration zur Laufzeit erstellt. Dieses Objekt wird in einer produktiven Applikation meisten durch die XML Datei hibernate.cfg.xml konfiguriert. Für das kleine Beispiel genügt es uns, wenn die Configuration im Quellcode erstellt wird.
Nun weiss Hibernate, dass wir uns auf eine Hybersonic Datenbank verbinden wollen.

public static void main(String[] args)
{
SchemaExport exporter = new SchemaExport(config);
exporter.setOutputFile("cone.sql");
exporter.setDelimiter(";"); // Setze ein Semikolon ans Ende des SQL Statments
exporter.create(true, false); // Skript nicht mit der DB aktualisieren aber auf der Konsole ausgeben.
}

In der Hibernate API existiert eine Klasse namens SchemaExport mit welcher man sehr einfach aus einer Hibernate Mapping Datei ein SQL Skript erstellen kann bzw. das Skript direkt via der konfigurierten JDBC Verbindung von Hibernate auf der Datenbank ausführen kann. Diese Klasse bzw. eine Erweiterung davon SchemaExportTask lässt sich auch als Task in Ant einbinden. Nachdem die Methode main ausgeführt wurde, kann man sowohl in der Datei cone.sql als auch auf der Console (stdout) das nachfolgende SQL Skript sehen. Dieses Skript ist im HSQLDB SQL Dialect erstellt worden und kann daher problemlos auf der Hybersonic Datenbank ausgeführt werden.

drop table tbl_filenet_user if exists;
create table tbl_filenet_user (
fn_id integer generated by default as identity (start with 1),
fn_usr varchar(30) not null,
fn_pwd varchar(30),
primary key (fn_id)
);

No comments: