myHead

Jarosław Kijanowski


Drools trifft Hibernate

Inhaltsangabe:

Drools arbeitet mit Objekten, auch Fakten genannt, die sich in der Working Memory befinden. Aber könnte auch eine Datenbank nach Fakten 'abgefragt' werden? Weil diese Möglichkeit ganz neue Türen öffnen würde und weil dies eine häufig in der Mailingliste gestellte Frage ist, ist es gut zu wissen, dass die Antwort "Ja, natürlich!" lautet.

Hibernate, eines der populärsten ORM Tools, ermöglicht es Daten aus einer relationalen Datenbank zu verwalten. Dieser Artikel zeigt, wie Regeln, mit Hilfe einer Hibernate Session, in der Datenbank sich befindende Objekte benützen können. Als Datenbank wird PostgreSQL dienen. Es werden auch zwei Klassen gezeigt, die eine viele-zu-viele Beziehung haben und deren Objekte sich in der Datenbank befinden.

  1. Ein neues Drools Projekt
  2. Klassen
  3. Hibernate
  4. Drools
  5. Was ist passiert?
  6. Ergebnisse
  7. Zusammenfassung

  1. Ein neues Drools Projekt

    Das Drools 4.0.7 Eclipse Workbench ist noch nich installiert? Der Artikel "In der Not frisst der Teufel Regeln" zeigt wie.

  2. Menu File -> New -> Project -> Drools - > Rule Project -> Next. Als Projektnamen geben wir drools-hibernate-demo an und wählen Next, um die Beispiel-Dateien zu deaktivieren.

  3. Klassen
  4. Im Verzeichnis src/main/java erstellen wir ein neues Package "eu.kijanowski.drools.hibernate". Wie schon erwähnt werden wir zwei Klassen haben, einen Spieler (Player.java) und ein Spiel (Game.java), zwischen welchen eine viele-zu-viele Beziehung besteht, denn ein Spieler kann mehrere Spiele besitzen, und ein Spiel kann vielen Spielern gehören ;)

    Klasse Game.java

    package eu.kijanowski.drools.hibernate;
    
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    public class Game implements Serializable {
    	private static final long serialVersionUID = 1L;
    	private Long id = null;
    	private String name;
    	private double price;
    	private int levels;
    	private Set<Player> players = new HashSet<Player>();
    
    	public Game() {
    	}
    
    	public Game(String name, double price, int levels) {
    		this.name = name;
    		this.price = price;
    		this.levels = levels;
    	}
    
    	public Long getId() {
    		return id;
    	}
    
    	@SuppressWarnings("unused")
    	private void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public double getPrice() {
    		return price;
    	}
    
    	public void setPrice(double price) {
    		this.price = price;
    	}
    
    	public int getLevels() {
    		return levels;
    	}
    
    	public void setLevels(int levels) {
    		this.levels = levels;
    	}
    
    	public Set<Player> getPlayers() {
    		return players;
    	}
    
    	public void setPlayers(Set<Player> players) {
    		this.players = players;
    	}
    
    	public String toString() {
    		return name + " with " + levels + " levels for " + price;
    	}
    }
    	

    Klasse Player.java

    package eu.kijanowski.drools.hibernate;
    
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Set;
    
    public class Player implements Serializable {
    	private static final long serialVersionUID = 1L;
    	private Long id;
    	private String name;
    	private int age;
    	private Set<Game> games = new HashSet<Game>();
    
    	public Player() {
    	}
    
    	public Player(String name, int age, HashSet<Game> games) {
    		this.name = name;
    		this.age = age;
    		this.games = games;
    	}
    
    	public Long getId() {
    		return id;
    	}
    
    	@SuppressWarnings("unused")
    	private void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public Set<Game> getGames() {
    		return games;
    	}
    
    	public void setGames(Set<Game> games) {
    		this.games = games;
    	}
    
    	public String toString() {
    		return name;
    	}
    }	
    
  5. Hibernate
  6. Ohne ins Detail zu gehen, laden wir Hibernate Core 3.2.6 herunter und entpacken das Archiv.

    In unserem Projekt erstellen wir ein neues Verzeichnis "lib", wo wir folgende Dateien kopieren:

    • hibernate-3.2.6.GA/lib/antlr-2.7.6.jar

    • hibernate-3.2.6.GA/lib/asm.jar

    • hibernate-3.2.6.GA/lib/cglib-2.1.3.jar

    • hibernate-3.2.6.GA/lib/commons-collections-2.1.1.jar

    • hibernate-3.2.6.GA/lib/commons-logging-1.0.4.jar

    • hibernate-3.2.6.GA/lib/dom4j-1.6.1.jar

    • hibernate-3.2.6.GA/hibernate3.jar

    • hibernate-3.2.6.GA/lib/jta.jar

    All diese Bibliotheken müssen num im "build path" aufgenommen werden: Aus dem Menu Project -> Properties -> Java Build Path -> Libraries wählen wir Add External JARs und deuten auf das "lib" Verzeichnis unseres Projektes. Nachdem ale Dateien markiert wurden, klicken wir auf OK.

    Bevor wir Hibernate nützen können, müssen wir es zuvor konfigurieren, im Verzeichnis src/main/java erstellen wir die Datei hibernate.cfg.xml:

    <?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>
             <property name="connection.driver_class">org.postgresql.Driver</property>
             <property name="connection.url">jdbc:postgresql://localhost/droolsdb</property>
             <property name="connection.username">droolsuser</property>
             <property name="connection.password"></property>
             <property name="connection.pool_size">1</property>
             <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
             <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
             <property name="current_session_context_class">thread</property>
             <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
             <property name="show_sql">true</property>
             <property name="hbm2ddl.auto">create</property>
             <mapping resource="eu/kijanowski/drools/hibernate/model.hbm.xml"/>
         </session-factory>
     </hibernate-configuration>
     

    Da wir den org.postgresql.Driver Treiber angegeben haben, müssen wir für die entsprechende Bibliothek sorgen und sie in das "lib" Verzeichnis kopieren. Von der Home Page des PostgreSQL Anbieters können wir die gewünschten Treiber herunterladen. In dieser Beispielsanwendung wurde 8.2-508 JDBC 3 ausgewählt. Diese Bibliothek, genau wie die Hibernate Bibliotheken, muss zum Java Build Path dazu gegeben werden.

    Höchste Zeit um die PostgreSQL Datenbank herunterzuladen um sie anschliessend zu starten und einen Benutzer und ein Schema anzulegen.

    /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 &
    /usr/local/pgsql/bin/createuser -h 127.0.0.1 -p 5432 -U postgres -s -d -R droolsuser
    /usr/local/pgsql/bin/createdb -h 127.0.0.1 -p 5432 -U postgres -O droolsuser droolsdb

    Der letzte Schritt in der Hibernatekonfiguration ist das Mapping, also die Abbildung der Java Welt und derer Objekte in die Welt der Relationen (Tabellen). Im Package eu.kijanowski.drools.hibernate erstellen wir die Datei model.hbm.xml:

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="eu.kijanowski.drools.hibernate">
    	<class name="Player" table="PLAYERS">
    		<id name="id" column="PLAYER_ID" type="java.lang.Long">
    			<generator class="sequence">
    				<param name="sequence">player_id_seq</param>
    			</generator>
    		</id>
    		<property name="name" column="NAME" length="10" not-null="true"
    			type="java.lang.String" />
    		<property name="age" column="AGE" not-null="true"
    			type="java.lang.Integer" />
    
    		<set name="games" table="PLAYERS_GAMES" cascade="persist, delete, merge, save-update">
    			<key column="PLAYER_ID" />
    			<many-to-many column="GAME_ID" class="Game" />
    		</set>
    		
    	</class>
    
    	<class name="Game" table="GAMES">
    		<id name="id" column="GAME_ID" type="java.lang.Long">
    			<generator class="sequence">
    				<param name="sequence">game_id_seq</param>
    			</generator>
    		</id>
    		<property name="name" column="NAME" length="10" not-null="true"
    			type="java.lang.String" />
    		<property name="price" column="PRICE" not-null="true"
    			type="java.lang.Double" />
    		<property name="levels" column="LEVELS" not-null="true"
    			type="java.lang.Integer" />
    		<set name="players" table="PLAYERS_GAMES">
    			<key column="GAME_ID" />
    			<many-to-many column="PLAYER_ID" class="Player"/>
    		</set>
    		
    	</class>
    </hibernate-mapping>
    
  7. Drools
  8. Was fehlt ist die Testklasse die unser Beispiel startet und natürlich die Datei mit der Regel, die nun Objekte aus der Datenbank auswerten wird. Um das zu erreichen werden wir in der Testklasse eine Hibernate Session erzeugen und sie den Regeln in Form einer globalen Konstante zur Verfügung stellen. Als nächstes wird in einer Regel eine Suchanfrage erstellt, deren Resultat mit Hilfe des "from" Schlüsselwortes nach Fakten durchsucht wird. Also ans Werk!

    Klasse DroolsHibernateTest.java

    package eu.kijanowski.drools.hibernate;
    
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import org.drools.RuleBase;
    import org.drools.RuleBaseFactory;
    import org.drools.WorkingMemory;
    import org.drools.compiler.PackageBuilder;
    import org.drools.rule.Package;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    
    public class DroolsHibernateTest {
    
    	private final static SessionFactory factory;
    	static {
    		Configuration cfg = new Configuration().configure();
    		factory = cfg.buildSessionFactory();
    	}
    
    	public static final void main(String[] args) {
    		try {
    
    			Game g1 = new Game("BF2", 39.99, 5);
    			Game g2 = new Game("AoE3", 129.99, 45);
    			Game g3 = new Game("BF3", 139.99, 15);
    
    			HashSet<Game> games1 = new HashSet<Game>();
    			games1.add(g1);
    			games1.add(g2);
    			games1.add(g3);
    			HashSet<Game> games2 = new HashSet<Game>();
    			games2.add(g1);
    			games2.add(g3);
    
    			Player p1 = new Player("jarek", 26, games1);
    			Player p2 = new Player("ewelina", 25, games2);
    
    			System.out.println(p1.getGames());
    			System.out.println(p2.getGames());
    
    			/* open a Hibernate session and persist data */
    			Session session = factory.openSession();
    			Transaction tx = session.beginTransaction();
    			session.save(p1);
    			session.save(p2);
    			tx.commit();
    			session.close();
    
    			/* Let's verify the persisted data */
    			session = factory.openSession();
    			tx = session.beginTransaction();
    
    			List<Player> players = session.createCriteria(Player.class).list();
    			System.out.println(players.size() + " player(s) found:");
    			for (Iterator<Player> iter = players.iterator(); iter.hasNext();) {
    				Player player = (Player) iter.next();
    				System.out.println(player.getName() + " has following games: "
    						+ player.getGames());
    			}
    			tx.commit();
    			session.close();
    
    			// load up the rulebase
    			RuleBase ruleBase = readRule();
    			WorkingMemory workingMemory = ruleBase.newStatefulSession();
    
    			/* pass a hibernate session to the working memory as a global */
    			session = factory.openSession();
    			workingMemory.setGlobal("hibernateSession", session);
    
    			workingMemory.fireAllRules();
    			session.close();
    
    		} catch (Throwable t) {
    			t.printStackTrace();
    		}
    	}
    
    	private static RuleBase readRule() throws Exception {
    		// read in the source
    		Reader source = new InputStreamReader(DroolsHibernateTest.class
    				.getResourceAsStream("/Demo.drl"));
    
    		PackageBuilder builder = new PackageBuilder();
    
    		// this will parse and compile in one step
    		builder.addPackageFromDrl(source);
    
    		// get the compiled package (which is serializable)
    		Package pkg = builder.getPackage();
    
    		// add the package to a rulebase (deploy the rule package).
    		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
    		ruleBase.addPackage(pkg);
    		return ruleBase;
    	}
    
    }
    
    	

    Die Datei mit der Regel erstellen wir mit Hilfe des Drools Plug-in. Dazu wählen wir das Verzeichnis src/main/rules und aus dem Menu File -> New -> Other... klicken wir auf Drools -> Rule Resource:

    Demo.drl

    package eu.kijanowski.drools.hibernate
    
    global org.hibernate.Session hibernateSession;
     
    rule "hibernate_from"
    	when
    		game:Game() from hibernateSession.createQuery("select games from Player p where p.age >= :age").setProperties( {"age" : 18 }).list()
    	then
    		System.out.println("The game "+game.getName() +"is owned by "+game.getPlayers());
    end
    	
  9. Was ist passiert?
  10. Eine wichtige Rolle spielt das Schlüsselwort global. Mit seiner Hilfe ermöglichen wir der Rule Engine Zugang zu Variablen und Konstanten aus unserer Anwendung. Am häufigsten erlauben sie:

    • den Regeln Informationen an die Anwendung zurückzugeben,

    • Zugang zu Diensten wie Hibernate Session, JMS, aber auch eigenen, die zum Beispiel E-mails versenden oder Dateien auf der Festplatte speichern.

    Man muss sich darüber im Klaren sein, dass globale Variablen innerhalb der Regel-Aktionen nicht verändert werden dürfen, wenn sie in Regel-Bedingungen (LHS) auftauchen. Zudem dienen sie nicht dem Austausch von Informationen mit anderen Regeln. Dies sollte mit Hilfe von Fakten, also Objekten die in die Working Memory hinzugefügt werden, geschehen.

    Das Schlüsselwort from hingegen erlaubt es andere, als die Working Memory, Quellen abzufragen. Dazu gehoren Collections, Maps, aber auch Resultate von Funktionen. In unsererm Beispiel haben wir mit Hilfe einer Hibernate Session eine Datenbankabfrage gestartet und eine Liste von Game Objekten erhalten, die dann in der Regel-Aktion ausgewertet wurden. Mehr Informationen über die hier vorgestellten Schlüsselwörter befinden sich in der Drools Dokumentation.

  11. Ergebnisse
  12. Nachdem wir unsere Anwendung gestartet haben (Run as -> Java Application) sollte Folgendes auf der Konsole erscheinen:

    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Environment <clinit>
    INFO: Hibernate 3.2.6
    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Environment <clinit>
    INFO: hibernate.properties not found
    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Environment buildBytecodeProvider
    INFO: Bytecode provider name : cglib
    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Environment <clinit>
    INFO: using JDK 1.4 java.sql.Timestamp handling
    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Configuration configure
    INFO: configuring from resource: /hibernate.cfg.xml
    Jun 14, 2008 8:58:11 AM org.hibernate.cfg.Configuration getConfigurationInputStream
    INFO: Configuration resource: /hibernate.cfg.xml
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.Configuration addResource
    INFO: Reading mappings from resource : eu/kijanowski/drools/hibernate/model.hbm.xml
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues
    INFO: Mapping class: eu.kijanowski.drools.hibernate.Player -> PLAYERS
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.HbmBinder bindCollection
    INFO: Mapping collection: eu.kijanowski.drools.hibernate.Player.games -> PLAYERS_GAMES
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues
    INFO: Mapping class: eu.kijanowski.drools.hibernate.Game -> GAMES
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.HbmBinder bindCollection
    INFO: Mapping collection: eu.kijanowski.drools.hibernate.Game.players -> PLAYERS_GAMES
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.Configuration doConfigure
    INFO: Configured SessionFactory: null
    Jun 14, 2008 8:58:12 AM org.hibernate.connection.DriverManagerConnectionProvider configure
    INFO: Using Hibernate built-in connection pool (not for production use!)
    Jun 14, 2008 8:58:12 AM org.hibernate.connection.DriverManagerConnectionProvider configure
    INFO: Hibernate connection pool size: 1
    Jun 14, 2008 8:58:12 AM org.hibernate.connection.DriverManagerConnectionProvider configure
    INFO: autocommit mode: false
    Jun 14, 2008 8:58:12 AM org.hibernate.connection.DriverManagerConnectionProvider configure
    INFO: using driver: org.postgresql.Driver at URL: jdbc:postgresql://localhost/droolsdb
    Jun 14, 2008 8:58:12 AM org.hibernate.connection.DriverManagerConnectionProvider configure
    INFO: connection properties: {user=droolsuser, password=****}
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: RDBMS: PostgreSQL, version: 8.2.5
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC driver: PostgreSQL Native Driver, version: PostgreSQL 8.2 JDBC3 with SSL (build 508)
    Jun 14, 2008 8:58:12 AM org.hibernate.dialect.Dialect <init>
    INFO: Using dialect: org.hibernate.dialect.PostgreSQLDialect
    Jun 14, 2008 8:58:12 AM org.hibernate.transaction.TransactionFactoryFactory buildTransactionFactory
    INFO: Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
    Jun 14, 2008 8:58:12 AM org.hibernate.transaction.TransactionManagerLookupFactory getTransactionManagerLookup
    INFO: No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Automatic flush during beforeCompletion(): disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Automatic session close at end of transaction: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC batch size: 15
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC batch updates for versioned data: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Scrollable result sets: enabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JDBC3 getGeneratedKeys(): disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Connection release mode: auto
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Default batch fetch size: 1
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Generate SQL with comments: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Order SQL updates by primary key: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Order SQL inserts for batching: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory createQueryTranslatorFactory
    INFO: Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
    Jun 14, 2008 8:58:12 AM org.hibernate.hql.ast.ASTQueryTranslatorFactory <init>
    INFO: Using ASTQueryTranslatorFactory
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Query language substitutions: {}
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: JPA-QL strict compliance: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Second-level cache: enabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Query cache: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory createCacheProvider
    INFO: Cache provider: org.hibernate.cache.NoCacheProvider
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Optimize cache for minimal puts: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Structured second-level cache entries: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Echoing all SQL to stdout
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Statistics: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Deleted entity synthetic identifier rollback: disabled
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Default entity-mode: pojo
    Jun 14, 2008 8:58:12 AM org.hibernate.cfg.SettingsFactory buildSettings
    INFO: Named query checking : enabled
    Jun 14, 2008 8:58:12 AM org.hibernate.impl.SessionFactoryImpl <init>
    INFO: building session factory
    Jun 14, 2008 8:58:12 AM org.hibernate.impl.SessionFactoryObjectFactory addInstance
    INFO: Not binding factory to JNDI, no JNDI name configured
    Jun 14, 2008 8:58:12 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
    INFO: Running hbm2ddl schema export
    Jun 14, 2008 8:58:12 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
    INFO: exporting generated schema to database
    Jun 14, 2008 8:58:13 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
    INFO: schema export complete
    [BF3 with 15 levels for 139.99, BF2 with 5 levels for 39.99, AoE3 with 45 levels for 129.99]
    [BF3 with 15 levels for 139.99, BF2 with 5 levels for 39.99]
    Hibernate: select nextval ('player_id_seq')
    Hibernate: select nextval ('game_id_seq')
    Hibernate: select nextval ('game_id_seq')
    Hibernate: select nextval ('game_id_seq')
    Hibernate: select nextval ('player_id_seq')
    Hibernate: insert into PLAYERS (NAME, AGE, PLAYER_ID) values (?, ?, ?)
    Hibernate: insert into GAMES (NAME, PRICE, LEVELS, GAME_ID) values (?, ?, ?, ?)
    Hibernate: insert into GAMES (NAME, PRICE, LEVELS, GAME_ID) values (?, ?, ?, ?)
    Hibernate: insert into GAMES (NAME, PRICE, LEVELS, GAME_ID) values (?, ?, ?, ?)
    Hibernate: insert into PLAYERS (NAME, AGE, PLAYER_ID) values (?, ?, ?)
    Hibernate: insert into PLAYERS_GAMES (PLAYER_ID, GAME_ID) values (?, ?)
    Hibernate: insert into PLAYERS_GAMES (PLAYER_ID, GAME_ID) values (?, ?)
    Hibernate: insert into PLAYERS_GAMES (PLAYER_ID, GAME_ID) values (?, ?)
    Hibernate: insert into PLAYERS_GAMES (PLAYER_ID, GAME_ID) values (?, ?)
    Hibernate: insert into PLAYERS_GAMES (PLAYER_ID, GAME_ID) values (?, ?)
    Hibernate: select this_.PLAYER_ID as PLAYER1_0_0_, this_.NAME as NAME0_0_, this_.AGE as AGE0_0_ from PLAYERS this_
    2 player(s) found:
    Hibernate: select games0_.PLAYER_ID as PLAYER1_1_, games0_.GAME_ID as GAME2_1_, game1_.GAME_ID as GAME1_2_0_, game1_.NAME as NAME2_0_, game1_.PRICE as PRICE2_0_, game1_.LEVELS as LEVELS2_0_ from PLAYERS_GAMES games0_ left outer join GAMES game1_ on games0_.GAME_ID=game1_.GAME_ID where games0_.PLAYER_ID=?
    jarek has following games: [AoE3 with 45 levels for 129.99, BF3 with 15 levels for 139.99, BF2 with 5 levels for 39.99]
    Hibernate: select games0_.PLAYER_ID as PLAYER1_1_, games0_.GAME_ID as GAME2_1_, game1_.GAME_ID as GAME1_2_0_, game1_.NAME as NAME2_0_, game1_.PRICE as PRICE2_0_, game1_.LEVELS as LEVELS2_0_ from PLAYERS_GAMES games0_ left outer join GAMES game1_ on games0_.GAME_ID=game1_.GAME_ID where games0_.PLAYER_ID=?
    ewelina has following games: [BF3 with 15 levels for 139.99, BF2 with 5 levels for 39.99]
    Hibernate: select game2_.GAME_ID as GAME1_2_, game2_.NAME as NAME2_, game2_.PRICE as PRICE2_, game2_.LEVELS as LEVELS2_ from PLAYERS player0_ inner join PLAYERS_GAMES games1_ on player0_.PLAYER_ID=games1_.PLAYER_ID inner join GAMES game2_ on games1_.GAME_ID=game2_.GAME_ID where player0_.AGE>=?
    Hibernate: select players0_.GAME_ID as GAME2_1_, players0_.PLAYER_ID as PLAYER1_1_, player1_.PLAYER_ID as PLAYER1_0_0_, player1_.NAME as NAME0_0_, player1_.AGE as AGE0_0_ from PLAYERS_GAMES players0_ left outer join PLAYERS player1_ on players0_.PLAYER_ID=player1_.PLAYER_ID where players0_.GAME_ID=?
    The game BF2is owned by [jarek, ewelina]
    Hibernate: select players0_.GAME_ID as GAME2_1_, players0_.PLAYER_ID as PLAYER1_1_, player1_.PLAYER_ID as PLAYER1_0_0_, player1_.NAME as NAME0_0_, player1_.AGE as AGE0_0_ from PLAYERS_GAMES players0_ left outer join PLAYERS player1_ on players0_.PLAYER_ID=player1_.PLAYER_ID where players0_.GAME_ID=?
    The game BF3is owned by [jarek, ewelina]
    Hibernate: select players0_.GAME_ID as GAME2_1_, players0_.PLAYER_ID as PLAYER1_1_, player1_.PLAYER_ID as PLAYER1_0_0_, player1_.NAME as NAME0_0_, player1_.AGE as AGE0_0_ from PLAYERS_GAMES players0_ left outer join PLAYERS player1_ on players0_.PLAYER_ID=player1_.PLAYER_ID where players0_.GAME_ID=?
    The game AoE3is owned by [jarek]
    The game BF2is owned by [jarek, ewelina]
    The game BF3is owned by [jarek, ewelina]	
    	
  13. Zusammenfassung
  14. Dieser Artikel hat gezeigt wie einfach es ist sich Hibernate in einer typischen Drools Anwendung zu Nutzen zu machen. Das erlaubt es uns Fakten abzufragen die sich nicht nur in der Working Memory befinden, aber auch in einer relationellen Datenbank.

Hier können Kommentare abgegeben werden.