[jboss-cvs] JBossAS SVN: r82570 - in projects/ejb3/trunk/docs/tutorial/guide: en and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Dec 31 04:00:41 EST 2008


Author: jaikiran
Date: 2008-12-31 04:00:40 -0500 (Wed, 31 Dec 2008)
New Revision: 82570

Added:
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/blob.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/callbacks.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/composite.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateful.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml
Modified:
   projects/ejb3/trunk/docs/tutorial/guide/en/master.xml
   projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateless.xml
   projects/ejb3/trunk/docs/tutorial/guide/pom.xml
Log:
More tutorials added to the guide

Modified: projects/ejb3/trunk/docs/tutorial/guide/en/master.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/master.xml	2008-12-30 22:17:35 UTC (rev 82569)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/master.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -2,6 +2,11 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN" "../../../../docbook-support/support/docbook-dtd/docbookx.dtd" [
 <!ENTITY installing          SYSTEM "modules/installing.xml">
 <!ENTITY stateless          SYSTEM "modules/stateless.xml">
+<!ENTITY stateful          SYSTEM "modules/stateful.xml">
+<!ENTITY blob          SYSTEM "modules/blob.xml">
+<!ENTITY callbacks          SYSTEM "modules/callbacks.xml">
+<!ENTITY composite          SYSTEM "modules/composite.xml">
+<!ENTITY todo          SYSTEM "modules/todo.xml">
 ]>
 <book lang="en">
   <bookinfo>
@@ -14,5 +19,5 @@
     <title>Target Audience</title>
     <para>This tutorial is meant for EJB3 application developers on JBoss Application Server. The tutorial walks you through the EJB 3.0 features and how they deploy to JBoss.  Please check the <xref linkend="Installation">install guide</xref> for system requirements.</para>
   </preface>
-&installing;&stateless;
+&installing;&stateless;&stateful;&blob;&callbacks;&composite;&todo;
 </book>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/blob.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/blob.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/blob.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -0,0 +1,215 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Blob and Clob support in EJB3">
+	<title>Introduction to Blob and Clob support in EJB3</title>
+	<para>
+	The EJB 3.0 specification has support for Blob and Clob types.  The specification allows you to map the following types to
+an entity property:
+		<itemizedlist mark="opencircle">
+			<listitem>
+				<para>
+					<literal>java.sql.Blob</literal>
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					<literal>java.sql.Clob</literal>
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					Any Serializable Object
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					byte[], Byte[]
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					char[], String, Character[]
+				</para>
+			</listitem>
+			
+		</itemizedlist>
+	</para>
+	
+	<para>
+	To use this feature just need to use the <literal>@javax.persistence.Lob</literal> annotation. The <literal>Lob</literal> annotation is an
+	encapsulation of what type of lob you want.  Below is an example of defining fields in an entity that are blobs or clobs.
+	
+		<programlisting>
+ at Entity
+public class BlobEntity implements Serializable
+{
+   private long id;
+   private Blob blobby;
+   private Clob clobby;
+
+   @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
+   public long getId()
+   {
+      return id;
+   }
+
+   public void setId(long id)
+   {
+      this.id = id;
+   }
+
+   @Lob @Basic(fetch = FetchType.EAGER)
+   public Blob getBlobby()
+   {
+      return blobby;
+   }
+
+   public void setBlobby(Blob blobby)
+   {
+      this.blobby = blobby;
+   }
+
+   @Lob @Basic(fetch = FetchType.EAGER)
+   public Clob getClobby()
+   {
+      return clobby;
+   }
+
+   public void setClobby(Clob clobby)
+   {
+      this.clobby = clobby;
+   }
+
+
+}
+		</programlisting>
+	</para>	
+	
+	<sect5>
+Working with Blobs and Clobs:
+	</sect5>
+	<para>
+Open up <literal>org.jboss.tutorial.blob.bean.LobTesterBean</literal> and look for the <literal>create()</literal> method. JBoss EJB3
+is built on top of the Hibernate persistence engine.  Hibernate has some helper methods for creating blobs and clobs that {{LobTesterBean}}
+uses.
+	</para>
+	<sect5>
+Blob creation:	
+	</sect5>
+	<para>
+		<literal>org.hibernate.Hibernate.createBlob(byte[] bytes)</literal>
+		<literal>org.hibernate.Hibernate.createBlob(InputStream stream, int length)</literal>
+		<literal>org.hibernate.Hibernate.createBlob(InputStream stream)</literal>
+	</para>
+	
+	<sect5>
+Clob creation:	
+	</sect5>
+	<para>
+		<literal>org.hibernate.Hibernate.createClob(String string)</literal>
+		<literal>org.hibernate.Hibernate.createClob(Reader reader, int length)</literal>
+	</para>
+	
+	<para>
+		Blobs and clobs must only be accessed within a transaction.  Blobs and clobs are also not serializable or detachable.
+	</para>	
+	
+	<sect5>
+Mapping Strings/byte[] to Clob/Blob:
+	</sect5>	
+	<para>
+		This is pretty easy, just look at BlobEntity2.java
+		
+		<programlisting>
+ at Entity
+public class BlobEntity2 implements Serializable
+{
+   private long id;
+   private byte[] blobby;
+   private String clobby;
+
+   @Id @GeneratedValue(strategy=GenerationType.AUTO)
+   public long getId()
+   {
+      return id;
+   }
+
+   public void setId(long id)
+   {
+      this.id = id;
+   }
+
+   @Lob @Basic(fetch = FetchType.EAGER)
+   public byte[] getBlobby()
+   {
+      return blobby;
+   }
+
+   public void setBlobby(byte[] blobby)
+   {
+      this.blobby = blobby;
+   }
+
+   @Lob @Basic(fetch = FetchType.EAGER)
+   public String getClobby()
+   {
+      return clobby;
+   }
+
+   public void setClobby(String clobby)
+   {
+      this.clobby = clobby;
+   }
+
+
+}
+			
+		</programlisting>
+		
+	</para>
+	
+	<para>
+		<sect5>
+Building and Running:
+		</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+		<sect5>
+Ant Users:
+		</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+$ ant
+$ ant run
+
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+
+	</para>
+	
+	<sect5>
+View the tables and rows:
+	</sect5>
+	<para>
+		You can view the tables created by JBoss by going to the 
+		<ulink url="http://localhost:8080/jmx-console/HtmlAdaptor?action=inspectMBean&amp;name=jboss%3Aservice%3DHypersonic%2Cdatabase%3DlocalDB">Hypersonic Service</ulink>,
+		scrolling down to the <literal>startDatabaseManager</literal> button and clicking it.  
+		A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.
+	
+	</para>
+	
+</chapter>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/callbacks.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/callbacks.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/callbacks.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -0,0 +1,292 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Callbacks and Callback Handlers">
+	<title>Introduction to Callbacks and Callback Handlers in EJB3</title>
+	
+		The EJB 3.0 specification defines some callbacks, and allows you to handle these by implementing your own callback handlers.
+		The callbacks defined for each bean are shown below:
+		<itemizedlist mark="opencircle">
+			<listitem>
+				<para>
+					Stateless session bean callbacks
+					<itemizedlist mark="hyphen">
+						<listitem>
+								<literal>PostConstruct</literal> - is invoked when the bean is first created, after any dependency injection is done.
+						</listitem>
+						<listitem>
+								<literal>PreDestroy</literal> - is invoked when the bean is removed from the pool or destroyed.
+						</listitem>
+					</itemizedlist>
+				</para>
+			</listitem>
+			
+			<listitem>
+				<para>
+					Message-driven bean callbacks
+					<itemizedlist mark="hyphen">
+						<listitem>
+								<literal>PostConstruct</literal> - is invoked when the bean is first created, after any dependency injection is done.
+						</listitem>
+						<listitem>
+								<literal>PreDestroy</literal> - is invoked when the bean is removed from the pool or destroyed.
+						</listitem>
+					</itemizedlist>
+				</para>
+			</listitem>
+			
+			<listitem>
+				<para>
+					Stateful session bean callbacks
+					<itemizedlist mark="hyphen">
+						<listitem>
+								<literal>PostConstruct</literal> - is invoked when the bean is first created, after any dependency injection is done.
+						</listitem>
+						<listitem>
+								<literal>PreDestroy</literal> - is invoked when the bean is removed from the pool or destroyed. 
+								It will happen before any <literal>@Remove</literal> annotated method is invoked.
+						</listitem>
+						<listitem>
+								<literal>PostActivate</literal>
+						</listitem>
+						<listitem>
+								<literal>PrePassivate</literal>
+						</listitem>
+						
+					</itemizedlist>
+				</para>
+			</listitem>
+			
+			<listitem>
+				<para>
+					Entity bean callbacks
+					<itemizedlist mark="hyphen">
+						<listitem>
+								<literal>PrePersist</literal> - Is invoked right before the entity is created in the database. 
+								Will cascade to all entities to which this operation is cascaded.
+						</listitem>
+						<listitem>
+								<literal>PostPersist</literal> - Is invoked right after the entity is created in the database. 
+								Will cascade to all entities to which this operation is cascaded.
+						</listitem>
+						<listitem>
+								<literal>PreRemove</literal> - Is invoked right before the entity is deleted in the database. 
+								Will cascade to all entities to which this operation is cascaded.
+						</listitem>
+						<listitem>
+								<literal>PostRemove</literal> - Is invoked right after the entity is deleted in the database.
+								Will cascade to all entities to which this operation is cascaded.
+						</listitem>
+						<listitem>
+								<literal>PreUpdate</literal> - Takes place right before the database is updated.
+						</listitem>
+						<listitem>
+								<literal>PostUpdate</literal> - Takes place immediately after the database has been updated.
+						</listitem>
+						<listitem>
+								<literal>PostLoad</literal> - Takes place right after data has been loaded 
+								from the database and associated with the entity
+						</listitem>						
+					</itemizedlist>
+					The callbacks are not compulsory, and you can define the ones you want to handle.
+				</para>
+			</listitem>
+		</itemizedlist>
+		
+		<sect5>
+			Using callbacks on the bean class: 
+		</sect5>
+		<para>
+			You use the callbacks listed above by annotating methods in the bean class. 
+			The annotations live in the <literal>javax.ejb</literal> package so for example <literal>PostConstruct</literal>
+			would be <literal>javax.ejb.PostConstruct</literal>. You can call the methods what you like, but their method signature 
+			must return a void and take no arguments. Look at the <literal>org.jboss.tutorial.callback.bean.CustomerDAOBean</literal>
+			stateless session bean and you will see that the <literal>preDestroyCallback()</literal> method has been annotated with 
+			<literal>@javax.ejb.PreDestroy</literal>. For session/message-driven beans, just like for interceptors, if the bean class 
+			extends another class any callback annotated methods on the super class will be invoked first.
+		</para>
+				
+		<sect5>
+			Entity listeners for entity beans:
+		</sect5>
+		<para>
+			You can also separate out the callbacks for entity beans into a separate EntityListener class. Take a look at the 
+			<literal>org.jboss.tutorial.callback.bean.Customer</literal> entity bean, and you will see that the class has been annotated with
+			<literal>@javax.persistence.EntityListener("org.jboss.tutorial.callback.bean.CustomerCallbackListener")</literal>.
+			This specifies that the <literal>org.jboss.tutorial.callback.bean.CustomerCallbackListener</literal> class should be used as
+			the callback listener class for the bean. Now open <literal>org.jboss.tutorial.callback.bean.CustomerCalbackListener</literal>
+			and you will see that the class annotates the callback methods in the same way as when defining callbacks on the bean class itself.
+			However, one __important difference__ is that callback methods defined in a listener class must take a single argument, which will
+			be the bean we are working with. The parameter must be of type <literal>java.lang.Object</literal>, or the actual bean type.
+		</para>
+				
+		<sect5>
+			Interceptors for session/message-driven beans:
+		</sect5>
+		<para>
+			Callbacks for session beans can also be put into a separate class, configured as an interceptor.
+			This means that your interceptors can initialise themselves when constructed. The lifecycle methods in an interceptor
+			must have the following signature:
+		
+			<programlisting><![CDATA[Object <any method name>(InvocationContext)]]></programlisting>
+			<literal>org.jboss.tutorial.callback.bean.CustomerDAOBean</literal> specifies that it wants to use an external interceptor.
+			<programlisting>
+ at Stateless
+ at Remote(CustomerDAO.class)
+ at Interceptors({LifecycleInterceptor.class})
+public class CustomerDAOBean implements CustomerDAO
+{
+   ...
+}
+			</programlisting>
+		
+			and <literal>org.jboss.tutorial.callback.bean.LifecycleInterceptor</literal> has a <literal>@PostConstruct</literal> annotated method.
+			As shown, each interceptor lifecycle method must call <literal>proceed</literal> on the InvocationContext to invoke
+			the next interceptor. Interceptors may contain both the <literal>@AroundInvoke</literal> methods for intercepting 
+			business methods, and lifecycle methods. If you want to configure lifecycle methods for your interceptors with xml, 
+			you will need to do this in the <literal>interceptor</literal> section of ejb-jar.xml, and the keywords are 
+			<literal>post-construct-method</literal>, <literal>post-activate-method</literal>, <literal>pre-passivate-method</literal>
+			and <literal>pre-destry-method</literal>. For example:
+		
+			<programlisting><![CDATA[
+<ejb-jar>
+   <interceptors>
+      <interceptor>
+         <interceptor-class>org.acme.SomeInterceptor</interceptor-class>
+         <around-invoke-method>
+            <method-name>interceptorMethod</method-name>
+         </around-invoke-method>
+         <post-construct-method>
+            <method-name>sendCancelMessage</method-name>
+         </post-construct-method>
+         <pre-destroy-method>
+            <method-name>sendCancelMessage</method-name>
+         </pre-destroy-method>
+      </interceptor>   
+   </interceptors>
+</ejb-jar>]]>
+		
+			</programlisting>
+		
+			Interceptor methods for handling lifecycle events follow exactly the same ordering and inheritance rules as business method
+			interceptor methods, and an interceptor instance follows the lifecycle of the bean instance it is bound to.
+		
+		</para>
+	<para>
+		<sect5>
+Building and Running
+		</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+		<sect5>
+Ant Users:
+		</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+$ ant
+$ ant run
+
+run:
+     [java] Create Bill Burke and Monica Smith
+     [java] Bill and Monica get married
+     [java] Get all the Burkes
+     [java] There are now 2 Burkes
+     [java] Bill and Monica are moving abroad
+	</programlisting>
+
+	<sect5>
+Maven Users: TODO - In the current version, a single tutorials cannot be run using Maven. 
+Once the support is provided, the following command can be used
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+
+In the jboss console window you should see:
+
+	<programlisting><![CDATA[
+23:52:11,162 INFO  [STDOUT] LifecycleInterceptor postConstruct
+23:52:11,162 INFO  [STDOUT] PostConstruct - Have EntityManager: true
+23:52:11,424 INFO  [STDOUT] -- CustomerDAOBean.create()
+23:52:11,575 INFO  [STDOUT] doPrePersist: About to create Customer: Bill Burke
+23:52:11,608 INFO  [STDOUT] doPostPersist: Created Customer: Bill Burke
+23:52:11,644 INFO  [STDOUT] -- CustomerDAOBean.create()
+23:52:11,644 INFO  [STDOUT] doPrePersist: About to create Customer: Monica Smith
+23:52:11,645 INFO  [STDOUT] doPostPersist: Created Customer: Monica Smith
+23:52:11,655 INFO  [STDOUT] -- CustomerDAOBean.find()
+23:52:11,673 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Smith
+23:52:11,700 INFO  [STDOUT] -- CustomerDAOBean.merge()
+23:52:11,704 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Smith
+23:52:11,705 INFO  [STDOUT] doPreUpdate: About to update Customer: Monica Burke
+23:52:11,727 INFO  [STDOUT] doPostUpdate: Updated Customer: Monica Burke
+23:52:11,735 INFO  [STDOUT] -- CustomerDAOBean.findByLastName(id)
+23:52:12,101 INFO  [STDOUT] doPostLoad: Loaded Customer: Bill Burke
+23:52:12,102 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Burke
+23:52:12,113 INFO  [STDOUT] -- CustomerDAOBean.delete()
+23:52:12,116 INFO  [STDOUT] doPostLoad: Loaded Customer: Bill Burke
+23:52:12,118 INFO  [STDOUT] doPreRemove: About to delete Customer: Bill Burke
+23:52:12,124 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Burke
+23:52:12,125 INFO  [STDOUT] doPreRemove: About to delete Customer: Monica Burke
+23:52:12,128 INFO  [STDOUT] doPostRemove: Deleted Customer: Bill Burke
+23:52:12,128 INFO  [STDOUT] doPostRemove: Deleted Customer: Monica Burke
+	
+	]]></programlisting>
+	Now if you open up the persistence.xml, in this tutorial, and uncomment the following:
+	
+	
+	<programlisting><![CDATA[
+<property name="hibernate.show_sql" value="true"/>]]> 	
+	</programlisting>
+	and rebuild and run the tutorial, the output should be:
+	
+	<programlisting><![CDATA[
+00:00:24,514 INFO  [STDOUT] LifecycleInterceptor postConstruct
+00:00:24,514 INFO  [STDOUT] PostConstruct - Have EntityManager: true
+00:00:24,759 INFO  [STDOUT] -- CustomerDAOBean.create()
+00:00:24,760 INFO  [STDOUT] doPrePersist: About to create Customer: Bill Burke
+00:00:24,760 INFO  [STDOUT] Hibernate: insert into CUSTOMER (id, CITY, FIRST, LAST, STATE, STREET, ZIP) values (null, ?, ?, ?, ?, ?, ?)
+00:00:24,761 INFO  [STDOUT] Hibernate: call identity()
+00:00:24,762 INFO  [STDOUT] doPostPersist: Created Customer: Bill Burke
+00:00:24,773 INFO  [STDOUT] -- CustomerDAOBean.create()
+00:00:24,773 INFO  [STDOUT] doPrePersist: About to create Customer: Monica Smith
+00:00:24,774 INFO  [STDOUT] Hibernate: insert into CUSTOMER (id, CITY, FIRST, LAST, STATE, STREET, ZIP) values (null, ?, ?, ?, ?, ?, ?)
+00:00:24,774 INFO  [STDOUT] Hibernate: call identity()
+00:00:24,775 INFO  [STDOUT] doPostPersist: Created Customer: Monica Smith
+00:00:24,784 INFO  [STDOUT] -- CustomerDAOBean.find()
+00:00:24,785 INFO  [STDOUT] Hibernate: select customer0_.id as id8_0_, customer0_.CITY as CITY8_0_, customer0_.FIRST as FIRST8_0_, customer0_.LAST as LAST8_0_, customer0_.STATE as STATE8_0_, customer0_.STREET as STREET8_0_, customer0_.ZIP as ZIP8_0_ from CUSTOMER customer0_ where customer0_.id=?
+00:00:24,786 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Smith
+00:00:24,817 INFO  [STDOUT] -- CustomerDAOBean.merge()
+00:00:24,818 INFO  [STDOUT] Hibernate: select customer0_.id as id8_0_, customer0_.CITY as CITY8_0_, customer0_.FIRST as FIRST8_0_, customer0_.LAST as LAST8_0_, customer0_.STATE as STATE8_0_, customer0_.STREET as STREET8_0_, customer0_.ZIP as ZIP8_0_ from CUSTOMER customer0_ where customer0_.id=?
+00:00:24,818 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Smith
+00:00:24,818 INFO  [STDOUT] doPreUpdate: About to update Customer: Monica Burke
+00:00:24,820 INFO  [STDOUT] Hibernate: update CUSTOMER set CITY=?, FIRST=?, LAST=?, STATE=?, STREET=?, ZIP=? where id=?
+00:00:24,820 INFO  [STDOUT] doPostUpdate: Updated Customer: Monica Burke
+00:00:24,834 INFO  [STDOUT] -- CustomerDAOBean.findByLastName(id)
+00:00:24,880 INFO  [STDOUT] Hibernate: select customer0_.id as id8_, customer0_.CITY as CITY8_, customer0_.FIRST as FIRST8_, customer0_.LAST as LAST8_, customer0_.STATE as STATE8_, customer0_.STREET as STREET8_, customer0_.ZIP as ZIP8_ from CUSTOMER customer0_ where customer0_.LAST=?
+00:00:24,881 INFO  [STDOUT] doPostLoad: Loaded Customer: Bill Burke
+00:00:24,881 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Burke
+00:00:24,896 INFO  [STDOUT] -- CustomerDAOBean.delete()
+00:00:24,897 INFO  [STDOUT] Hibernate: select customer0_.id as id8_0_, customer0_.CITY as CITY8_0_, customer0_.FIRST as FIRST8_0_, customer0_.LAST as LAST8_0_, customer0_.STATE as STATE8_0_, customer0_.STREET as STREET8_0_, customer0_.ZIP as ZIP8_0_ from CUSTOMER customer0_ where customer0_.id=?
+00:00:24,897 INFO  [STDOUT] doPostLoad: Loaded Customer: Bill Burke
+00:00:24,898 INFO  [STDOUT] doPreRemove: About to delete Customer: Bill Burke
+00:00:24,898 INFO  [STDOUT] Hibernate: select customer0_.id as id8_0_, customer0_.CITY as CITY8_0_, customer0_.FIRST as FIRST8_0_, customer0_.LAST as LAST8_0_, customer0_.STATE as STATE8_0_, customer0_.STREET as STREET8_0_, customer0_.ZIP as ZIP8_0_ from CUSTOMER customer0_ where customer0_.id=?
+00:00:24,899 INFO  [STDOUT] doPostLoad: Loaded Customer: Monica Burke
+00:00:24,899 INFO  [STDOUT] doPreRemove: About to delete Customer: Monica Burke
+00:00:24,900 INFO  [STDOUT] Hibernate: delete from CUSTOMER where id=?
+00:00:24,900 INFO  [STDOUT] doPostRemove: Deleted Customer: Bill Burke
+00:00:24,900 INFO  [STDOUT] Hibernate: delete from CUSTOMER where id=?
+00:00:24,900 INFO  [STDOUT] doPostRemove: Deleted Customer: Monica Burke
+]]>	
+	
+	</programlisting>
+	Thus you can see how the callbacks on the entity bean wrap the interaction with the database.
+	</para>
+</chapter>
+	
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/composite.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/composite.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/composite.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -0,0 +1,201 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Composite Primary Keys for Entities in EJB3">
+	<title>Introduction to Composite Primary Keys and Primary Key Classes</title>
+	<para>
+	The EJB 3.0 specification allows you to define a primary key class as a <literal>@Embeddable</literal> and use it as the 
+	primary key of your Entity bean. One or more properties can be used as members of the primary key for that particular table.
+	This tutorial is an adaptation of the "relationships" tutorial. It adds a primary key class to Customer that holds both
+	the <literal>name</literal> and <literal>id</literal> of the Customer.
+	</para>
+	<programlisting>
+	<![CDATA[
+ at Embeddable
+public class CustomerPK implements java.io.Serializable
+{
+   private long id;
+   private String name;
+
+
+   public CustomerPK()
+   {
+   }
+
+   public CustomerPK(long id, String name)
+   {
+      this.id = id;
+      this.name = name;
+   }
+
+   public long getId()
+   {
+      return id;
+   }
+
+   public void setId(long id)
+   {
+      this.id = id;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   public int hashCode()
+   {
+      return (int) id + name.hashCode();
+   }
+
+   public boolean equals(Object obj)
+   {
+      if (obj == this) return true;
+      if (!(obj instanceof CustomerPK)) return false;
+      if (obj == null) return false;
+      CustomerPK pk = (CustomerPK) obj;
+      return pk.id == id && pk.name.equals(name);
+   }
+}
+]]>	
+	</programlisting>
+	
+	<sect5>
+	Mapping the primary key class:
+	</sect5>
+	
+	<para>
+		Open up <literal>org.jboss.tutorial.composite.bean.Customer</literal> and look for the <literal>getPk()</literal> method.
+		This defines the primary key class.
+		<programlisting>
+		<![CDATA[
+ at EmbeddedId
+public CustomerPK getPk()
+{
+   return pk;
+}
+		]]>
+		</programlisting>
+		
+		The <literal>org.jboss.tutorial.composite.bean.CustomerPK</literal> class is mapped to 
+		<literal>org.jboss.tutorial.composite.bean.Customer</literal> just like any other embeddable object.
+		The additional <literal>@EmbeddedId</literal> annotation specifies that it will be the primary key.
+		<note>
+			<para>
+				If you provide a primary key class, JBoss cannot auto-generate the key for you. You must allocate
+				a CustomerPK class and instantiate it with your id and name when you create the Customer.
+			</para>
+		</note>
+	</para>
+	
+	<sect5>
+		Many To Many
+	</sect5>
+	<para>
+		There is a many-to-many relationship between <literal>org.jboss.tutorial.composite.bean.Customer</literal> and 
+		<literal>org.jboss.tutorial.composite.bean.Flight</literal>. In order to have a many-to-many relationship there
+		needs to be a distinct join table that maps the many-to-many relationship. This is called an association table.
+  		You need to use the <literal>@JoinTable</literal> annotation to define this join table. The <literal>@JoinTable</literal>
+  		must be defined on both sides of the bi-directional relationship. Let's look at the Customer side of the relationship
+  		
+  		<programlisting>
+	  		<![CDATA[
+ at ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER, mappedBy="customers")
+ at JoinTable(name="flight_customer_table", joinColumns={@JoinColumn(name = "FLIGHT_ID")},
+          	inverseJoinColumns={@JoinColumn(name = "CUSTOMER_ID"), @JoinColumn(name = "CUSTOMER_NAME")})
+public Set<Flight> getFlights()
+{
+ 		return flights;
+}
+	  		]]>
+  		</programlisting>
+  		The <literal>mappedBy</literal> attribute specifies which side of the relationship is responsible for managing the relationship.
+  		If it is not set, then that side is responsible. So, for this example, the <literal>Flight</literal> Entity is responsible
+  		for managing the relation. In this example, we are specifying multiple <literal>inverseJoinColumns</literal>
+  		because Customer has a composite primary key.
+  		
+  		Let's look at the other side of the relationship in Flight:
+  		
+  		<programlisting>
+  			<![CDATA[
+ at ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
+ at JoinTable(name = "flight_customer_table", joinColumns = {@JoinColumn(name = "FLIGHT_ID")},
+         inverseJoinColumns = {@JoinColumn(name = "CUSTOMER_ID"), @JoinColumn(name = "CUSTOMER_NAME")})
+public Set<Customer> getCustomers()
+{
+	return customers;
+}
+  			]]>
+  		</programlisting>
+  		
+  		The <literal>Flight</literal> Entity must also define the <literal>@ManyToMany</literal> and <literal>@JoinTable</literal>.
+
+		The database associate table will look like this:
+		
+		<programlisting>
+		<![CDATA[
+create table FLIGHT_CUSTOMER_TABLE (
+  		CUSTOMER_ID integer,
+  		CUSTOMER_NAME varchar,
+  		FLIGHT_ID integer
+);
+		]]>
+		</programlisting>
+	</para>
+	
+	<sect5>
+Building and Running
+	</sect5>
+		
+		<note>
+			<para>
+	To build and run the example, make sure you have installed JBoss 5.x. 
+	See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+	<sect5>
+Ant Users:
+	</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+	<![CDATA[
+$ ant
+$ ant run
+
+run:
+     [java] Air France customers
+     [java] Bill
+     [java] Monica
+     [java] USAir customers
+     [java] Molly
+     ]]>
+	</programlisting>
+
+	<sect5>
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+	
+	<sect5>
+View the tables and rows:
+	</sect5>
+	<para>
+		You can view the tables created by JBoss by going to the 
+		<ulink url="http://localhost:8080/jmx-console/HtmlAdaptor?action=inspectMBean&amp;name=jboss%3Aservice%3DHypersonic%2Cdatabase%3DlocalDB">Hypersonic Service</ulink>,
+		scrolling down to the <literal>startDatabaseManager</literal> button and clicking it.  
+		A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.
+	
+	</para>
+	
+	
+	
+</chapter>
\ No newline at end of file

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateful.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateful.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateful.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -0,0 +1,85 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="Stateful Beans">
+	<title>Introduction to EJB3 Stateful Beans</title>
+
+	<para>
+	It is very easy to create a Stateful Bean with EJB 3.0. All bean types are homeless in EJB 3.0 so all you have to do to create a 
+	Stateful bean is to create a bean class and have it implement at least one interface. 
+	Take a look at <literal>org.jboss.tutorial.stateful.bean.ShoppingCartBean</literal> in the tutorial. 
+	</para>
+
+	<para>
+	The first thing to notice is that the class is tagged as <literal>@Stateful</literal>. This marks the class as a stateful bean and 
+	the deployer will deploy that class as a stateful bean EJB container.
+	</para>
+
+	<para>
+	ShoppingCartBean also implements a remote interface. Take a look at <literal>org.jboss.tutorial.stateful.bean.ShoppingCart</literal>
+	</para>
+
+	<para>
+		<sect4>
+ at Remove
+		</sect4>
+	Take another look at <literal>org.jboss.tutorial.stateful.bean.ShoppingCartBean</literal>. 
+	Look for the method annotated as @Remove. Instead of explicitly calling EJBObject.remove() in your applications and thus polluting it 
+	further with J2EE specific code, any method tagged with @Remove will cause the stateful bean instance to be removed from the container 
+	at the end of the method call.	
+	</para>
+
+	<para>
+		<sect4>
+JNDI Bindings
+		</sect4>
+	The ShoppingCartBean will have its remote interface bound in JNDI, by default, under the ejbName/local and/or ejbName/remote for 
+	the local and remote interfaces, respectively.
+	</para>
+
+	<para>
+		<sect4>
+Client
+		</sect4>
+	Open up <literal>org.jboss.tutorial.stateful.client.Client</literal>.
+  	You'll see that it looks up the stateful bean under "ejbName/remote". Also notice that there is no Home interface and you can begin 
+  	executing on the stateful bean right away. When you access the bean in JNDI, an instance of the stateful bean will be created on the server. 
+  	So, when you need a different instance of the stateful bean, you do an additional jndi.lookup() to get this new reference.
+
+	</para>
+
+	<para>
+		<sect4>
+Building and Running
+		</sect4>
+		
+		<note>
+			<para>
+			To build and run the example, make sure you have installed JBoss 5.x. 
+			See the <xref linkend="JBossAS5">installation section</xref> for details.
+			</para>
+		</note>
+
+		<sect5>
+Ant Users:
+		</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
+	<programlisting>
+$ ant
+$ ant run
+
+	</programlisting>
+
+	<sect5>
+Maven Users: TODO - In the current version, a single tutorials cannot be run using Maven. 
+Once the support is provided, the following command can be used
+	</sect5>
+	
+	<programlisting>
+$ mvn clean install
+	</programlisting>
+
+	</para>
+</chapter>
+	
+


Property changes on: projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateful.xml
___________________________________________________________________
Name: svn:executable
   + *

Modified: projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateless.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateless.xml	2008-12-30 22:17:35 UTC (rev 82569)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/stateless.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -4,7 +4,9 @@
 
 	<para>
 It is very easy to create a Stateless Bean with EJB 3.0.  All bean types are homeless in EJB 3.0 so all you have to do to
-create a Stateless bean is to create a bean class and have it implement at least one interface. Take a look at <ulink url="http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/docs/tutorial/stateless/src/org/jboss/tutorial/stateless/bean/CalculatorBean.java">CalculatorBean.java</ulink>
+create a Stateless bean is to create a bean class and have it implement at least one interface. Take a look at 
+<literal>org.jboss.tutorial.stateless.bean.CalculatorBean</literal>
+
 	</para>
 
 	<para>
@@ -17,24 +19,29 @@
 	</para>
 
 	<para>
-Take a look at <ulink url="http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/docs/tutorial/stateless/src/org/jboss/tutorial/stateless/bean/CalculatorRemote.java">CalculatorRemote.java</ulink>.  To define this as the remote interface of Calculator bean
+Take a look at <literal>org.jboss.tutorial.stateless.bean.CalculatorRemote</literal>.
+To define this as the remote interface of Calculator bean
 you either annotate the bean class and specify what the remote interfaces are, or you annotate each remote interface the bean class
-implements with @javax.ejb.Remote. only need to annotate the bean class with @javax.ejb.Remote.  Similar for <ulink url="http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/docs/tutorial/stateless/src/org/jboss/tutorial/stateless/bean/CalculatorLocal.java">CalculatorLocal.java</ulink> as you need to annotate the bean class with <literal>@javax.ejb.Local</literal> for it to be the local interface of the CalculatorBean.
+implements with @javax.ejb.Remote. only need to annotate the bean class with <literal>@javax.ejb.Remote</literal>.  
+Similar for <literal>org.jboss.tutorial.stateless.bean.CalculatorLocal</literal> as you need to annotate the bean 
+class with <literal>@javax.ejb.Local</literal> for it to be the local interface of the CalculatorBean.
 	</para>
 
 	<para>
 		<sect4>
 JNDI Bindings
 		</sect4>
-The Calculator bean will have two JNDI bindings for the remote and Local interface.  By default, JBoss will use ejbName/local and ejbName/remote for the local and
-remote interfaces, respectively.
+The Calculator bean will have two JNDI bindings for the remote and Local interface.  
+By default, JBoss will use ejbName/local and ejbName/remote for the local and remote interfaces, respectively.
 	</para>
 
 	<para>
 		<sect4>
 Client
 		</sect4>
-Open up <ulink link="http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/docs/tutorial/stateless/src/org/jboss/tutorial/stateless/client/Client.java">Client.java</ulink>.  You'll see that it looks up the stateless bean under "ejbName/remote". Also notice that there is no Home interface and you can begin executing on the stateless bean right away.
+Open up <literal>org.jboss.tutorial.stateless.client.Client</literal>.
+You'll see that it looks up the stateless bean under "ejbName/remote". Also notice that there is no Home interface and 
+you can begin executing on the stateless bean right away.
 
 	</para>
 
@@ -45,13 +52,17 @@
 		
 		<note>
 			<para>
-To build and run the example, make sure you have installed JBoss 5.x and have JBoss running. See the <xref linkend="JBossAS5">installation section</xref> for details.
+To build and run the example, make sure you have installed JBoss 5.x. 
+See the <xref linkend="JBossAS5">installation section</xref> for details.
 			</para>
 		</note>
 
 		<sect5>
 Ant Users:
 		</sect5>
+		<para>
+		Make sure your JBossAS-5.x is running
+		</para>
 	<programlisting>
 $ ant
 $ ant run
@@ -59,7 +70,7 @@
 	</programlisting>
 
 	<sect5>
-Maven Users:
+Maven Users: <xref linkend="Maven_Users_TODO">TODO</xref>
 	</sect5>
 	
 	<programlisting>

Added: projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml	                        (rev 0)
+++ projects/ejb3/trunk/docs/tutorial/guide/en/modules/todo.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<chapter id="TODO">
+	<title>TODO</title>
+
+
+		<section id="Maven_Users_TODO">
+			<title>TODO - Support for running single tutorial through Maven</title>
+			<para>
+				In the current version, a single tutorial cannot be run using Maven.
+				We have plans for adding this support. 
+			</para>
+
+		</section>
+		
+</chapter>
\ No newline at end of file

Modified: projects/ejb3/trunk/docs/tutorial/guide/pom.xml
===================================================================
--- projects/ejb3/trunk/docs/tutorial/guide/pom.xml	2008-12-30 22:17:35 UTC (rev 82569)
+++ projects/ejb3/trunk/docs/tutorial/guide/pom.xml	2008-12-31 09:00:40 UTC (rev 82570)
@@ -15,5 +15,7 @@
     <version>1.0.0-SNAPSHOT</version>
     <packaging>jdocbook</packaging>
     <name>JBoss EJB3 Tutorials</name>
+    
+    
 
 </project>




More information about the jboss-cvs-commits mailing list