Praktikum 4 zur Veranstaltung e-Commerce Prof. Dr. Nikolaus Wulff 2. Mai 2007 1 Persistenz per Hibernate In diesem Praktikum vereinfachen Sie noch einmal die Modellklassen. Statt jede Klasse per selbst geschriebenen Mapper in der Datenbank zu verwalten wird nun der Hibernate OR-Mapper verwendet. Hibernate bietet eine einfache Möglichkeit Klassen mit Hilfe von Annotations oder deklarativ per XML Beschreibung persistent zu machen. Die neuen Java Annotations sind hierbei die selben, die auch in der EJB3.0 Spezifikation verwendet werden. Dies hat den Vorteil, dass den Klassen von Außen nicht anzusehen ist, ob sie als EJBs innerhalb eines EJB-Containers oder als einfache ”Plain old Java Object” Klassen (POJO) verwendet werden. Im Quellcode (1) finden Sie ein einfaches Annotationbeispiel. Aufgabe 1. Um die Klassen persistent machen zu können, müssen Sie die Annotations @javax.persistence.Entity zum Kennzeichnen der peristenten Klassen verwenden. 2. Der Name der Table wird per @Table Annotation angegeben. 3. Die Getter-Methode des PrimaryKey Feld wird durch @Id annotiert. Um das ID-Feld automatisch zu generieren verwenden Sie als weitere Annotation @GeneratedValue(strategie=GenerationType.AUTO). 4. Weitere Annotationen müssen nicht explizit angegeben werden, da per default Hibernate alle Properties nach der Java Bean Konvention 1:1 peristent macht. 5. In der Datei hibernate.cfg.xml (2) muss ein entsprechender Vermerk stehen, um Ihre Klassen Hibernate kenntlich zu machen. Hier sind auch die Einstellungen für die Datenbankverbindung zu hinterlegen, die sich bislang in der web.xml befanden. 1 6. Das Speichern und Laden von Objekte erfolgt direkt mit der Hibernate Session, welche die Methoden load und save anbietet. Um Objekte per Query zu finden gibt es entsprechend zu SQL die HQL mit einer objektorientierten Syntax. Um ein Buch mit Namen JUnit zu finden lautet die entsprechende select-Anweisung: select o from Book o where o.title like ’JUnit’ Zurückgeliefert wird per query.list() Aufruf eine java.util.List gefüllt mit zum Suchkriterium passenden Büchern. 7. Passen Sie Ihre JUnit Tests entsprechend an, um die Persistenz per Hibernate automatisch testen zu können. Alle Ihren alten Testfälle müssen nach der Umstellung immer noch laufen. Tip Es emfiehlt sich eine gemeinsame Oberklasse für die Hibernatetests zu schreiben, die Hilfsmethoden für die Hibernate Session und Transaktionen zur Verfügung stellt. Code muss dann nicht unnötig dupliziert werden. Um die Schreibarbeit zu vereinfachen und alle benötigten Bibliotheken zu haben ist auf der Web-Site ein gepacktes Archiv zu finden, indem Sie ein Beispiel Hibernate Projekt finden. 2 @Entity @Table(name="book") public class Book { private Integer id; private String title; private String author; private String isbn; private String description; /** * @return the id */ @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } /** * @param id the id to set */ public void setId(Integer id) { this.id = id; } Abbildung 1: Book.java: Java (EJB) Peristent Annotions. 3 <?xml version=’1.0’ encoding=’utf-8’?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class"> org.gjt.mm.mysql.Driver</property> <property name="connection.url"> jdbc:mysql://konqueror/bookstore</property> <property name="connection.username"> bookstore</property> <property name="connection.password"> bookstore</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size"> 1</property> <!-- SQL dialect --> <property name="dialect"> org.hibernate.dialect.MySQLDialect</property> <!-- Enable Hibernate’s automatic session context management --> <property name="current_session_context_class"> thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class"> org.hibernate.cache.NoCacheProvider</property> <!-- Drop and re-create the database on startup --> <!-- property name="hbm2ddl.auto"> create</property --> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-- Auflistung der gemappten Klassen --> <mapping class="de.lab4inf.onlinestore.Book"/> </session-factory> </hibernate-configuration> Abbildung 2: hibernate.cfg.xml: Hibernate Konfiguration für MySQL. 4