[jboss-cvs] JBossAS SVN: r105077 - in projects/ejb-book/trunk: chxx-employeeregistry/src/test/java/org/jboss/ejb3/examples/employeeregistry and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu May 20 16:29:54 EDT 2010


Author: ALRubinger
Date: 2010-05-20 16:29:53 -0400 (Thu, 20 May 2010)
New Revision: 105077

Modified:
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Address.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Computer.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Customer.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Employee.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Phone.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Task.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Team.java
   projects/ejb-book/trunk/chxx-employeeregistry/src/test/java/org/jboss/ejb3/examples/employeeregistry/EmployeeIntegrationTest.java
   projects/ejb-book/trunk/testsupport/src/main/java/org/jboss/ejb3/examples/testsupport/entity/AutogenIdentityBase.java
Log:
[EJBBOOK-27] Added tests/examples for persistence relationship mappings

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Address.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Address.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Address.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -150,7 +150,7 @@
    @Override
    public String toString()
    {
-      return Address.class.getSimpleName() + " [city=" + city + ", state=" + state + ", street=" + street + "]";
+      return Address.class.getSimpleName() + " [city=" + city + ", state=" + state + ", street=" + street
+            + ", getId()=" + getId() + "]";
    }
-
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Computer.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Computer.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Computer.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -129,7 +129,8 @@
    @Override
    public String toString()
    {
-      return Computer.class.getSimpleName() + " [make=" + make + ", model=" + model + "]";
+      return Computer.class.getSimpleName() + " [make=" + make + ", model=" + model + ", owner=" + owner + ", getId()="
+            + getId() + "]";
    }
 
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Customer.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Customer.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Customer.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -115,14 +115,13 @@
    // Overridden Implementations ---------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
-   /**
-    * {@inheritDoc}
+   /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
-      return Customer.class.getSimpleName() + " [name=" + name + "]";
+      return Customer.class.getSimpleName() + " [name=" + name + ", getId()=" + getId() + "]";
    }
 
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Employee.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Employee.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Employee.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.ManyToMany;
 import javax.persistence.ManyToOne;
@@ -52,6 +53,9 @@
    /**
     * Name
     */
+   @Column(unique = true)
+   // No two employees are to have the same name; not exactly
+   // a real-world restriction, but shows usage. :)
    private String name;
 
    /**
@@ -77,7 +81,7 @@
    /**
     * {@link Employee}s reporting to this {@link Employee}
     */
-   @OneToMany(mappedBy = "peons")
+   @OneToMany(mappedBy = "manager")
    private Collection<Employee> peons;
 
    /**
@@ -237,14 +241,13 @@
    // Overridden Implementations ---------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
-   /**
-    * {@inheritDoc}
+   /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
-      return Employee.class.getSimpleName() + " [name=" + name + "]";
+      return Employee.class.getSimpleName() + " [name=" + name + ", getId()=" + getId() + "]";
    }
 
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Phone.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Phone.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Phone.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -102,7 +102,7 @@
    @Override
    public String toString()
    {
-      return Phone.class.getSimpleName() + " [number=" + number + ", type=" + type + "]";
+      return Phone.class.getSimpleName() + " [number=" + number + ", type=" + type + ", getId()=" + getId() + "]";
    }
 
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Task.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Task.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Task.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -126,6 +126,7 @@
    @Override
    public String toString()
    {
-      return Task.class.getSimpleName() + " [description=" + description + "]";
+      return Task.class.getSimpleName() + " [description=" + description + ", owners=" + owners + ", getId()="
+            + getId() + "]";
    }
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Team.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Team.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/main/java/org/jboss/ejb3/examples/employeeregistry/chxx/relationships/Team.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -67,6 +67,16 @@
       members = new ArrayList<Employee>();
    }
 
+   /**
+    * Convenience constructor
+    * @param name
+    */
+   public Team(final String name)
+   {
+      this();
+      this.name = name;
+   }
+
    //-------------------------------------------------------------------------------------||
    // Accessors / Mutators ---------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
@@ -114,6 +124,6 @@
    @Override
    public String toString()
    {
-      return Team.class.getSimpleName() + " [name=" + name + "]";
+      return Team.class.getSimpleName() + " [members=" + members + ", name=" + name + ", getId()=" + getId() + "]";
    }
 }

Modified: projects/ejb-book/trunk/chxx-employeeregistry/src/test/java/org/jboss/ejb3/examples/employeeregistry/EmployeeIntegrationTest.java
===================================================================
--- projects/ejb-book/trunk/chxx-employeeregistry/src/test/java/org/jboss/ejb3/examples/employeeregistry/EmployeeIntegrationTest.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/chxx-employeeregistry/src/test/java/org/jboss/ejb3/examples/employeeregistry/EmployeeIntegrationTest.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -22,6 +22,7 @@
 package org.jboss.ejb3.examples.employeeregistry;
 
 import java.util.Calendar;
+import java.util.Collection;
 import java.util.Date;
 import java.util.concurrent.Callable;
 import java.util.logging.Logger;
@@ -43,6 +44,7 @@
 import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.Customer;
 import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.Employee;
 import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.Phone;
+import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.PhoneType;
 import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.Task;
 import org.jboss.ejb3.examples.employeeregistry.chxx.relationships.Team;
 import org.jboss.ejb3.examples.employeeregistry.chyy.mapping.EmbeddedEmployeePK;
@@ -196,9 +198,8 @@
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(EmployeeWithMappedSuperClassId.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(EmployeeWithExternalCompositePK.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(EmployeeWithProperties.class, em);
-               EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Address.class, em);
+               EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Computer.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Phone.class, em);
-               EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Computer.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Customer.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Task.class, em);
                EmployeeIntegrationTest.this.deleteAllEntitiesOfType(Team.class, em);
@@ -663,6 +664,622 @@
       }
    }
 
+   /**
+    * Shows usage of the 1:1 Unidirectional Mapping Between
+    * {@link Employee} and {@link Address}
+    * @throws Throwable
+    */
+   @Test
+   public void oneToOneUnidirectionalMapping() throws Throwable
+   {
+      // Create a new Employee
+      final Employee alrubinger = new Employee("Andrew Lee Rubinger");
+
+      // Create a new Address
+      final Address address = new Address("1 JBoss Way", "Boston", "MA");
+
+      try
+      {
+         // Persist and associate an Employee and Address
+         final Long employeeId = txWrapper.wrapInTx(new Callable<Long>()
+         {
+
+            @Override
+            public Long call() throws Exception
+            {
+               // Get the EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(alrubinger);
+               em.persist(address);
+
+               // Associate
+               alrubinger.setAddress(address);
+
+               // Return
+               return alrubinger.getId();
+            }
+
+         });
+
+         // Now ensure when we look up the Address again by Employee after Tx has completed, 
+         // all's as expected
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get the EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Look up the employee 
+               final Employee roundtripEmployee = em.find(Employee.class, employeeId);
+
+               // Get the address
+               final Address persistedAddress = roundtripEmployee.getAddress();
+
+               // Ensure equal
+               Assert.assertEquals("Persisted address association was not as expected", address, persistedAddress);
+
+               // Clean up the association so we can remove
+               roundtripEmployee.setAddress(null);
+
+               // Return
+               return null;
+            }
+
+         });
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+
+   }
+
+   /**
+    * Shows usage of the 1:1 Bidirectional Mapping Between
+    * {@link Employee} and {@link Computer}
+    * @throws Throwable
+    */
+   @Test
+   public void oneToOneBidirectionalMapping() throws Throwable
+   {
+
+      // Create a new Computer
+      final Computer computer = new Computer();
+      computer.setMake("Computicorp");
+      computer.setModel("ZoomFast 100");
+
+      // Create a new Employee
+      final Employee carloDeWolf = new Employee("Carlo de Wolf");
+
+      try
+      {
+
+         /*
+          * We don't associate yet; our cascade policy will prohibit
+          * persisting entities with relationships that are not themselves 
+          * yet persisted
+          */
+
+         // Persist and associate
+         final Long employeeId = txWrapper.wrapInTx(new Callable<Long>()
+         {
+
+            @Override
+            public Long call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(carloDeWolf);
+               em.persist(computer);
+
+               // Associate *both* sides of a bidirectional relationship
+               carloDeWolf.setComputer(computer);
+               computer.setOwner(carloDeWolf);
+
+               // Return
+               return carloDeWolf.getId();
+            }
+         });
+
+         // Now check all was associated correctly
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get the EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the Employee
+               final Employee carloRoundtrip = em.find(Employee.class, employeeId);
+
+               // Get the Computer via the Employee
+               final Computer computerRoundtrip = carloRoundtrip.getComputer();
+
+               // Get the Employee via the Computer
+               final Employee ownerOfComputer = computer.getOwner();
+               log.info("Employee " + carloRoundtrip + " has computer " + computerRoundtrip);
+               log.info("Computer " + computerRoundtrip + " has owner " + ownerOfComputer);
+
+               // Assert all's as expected
+               Assert.assertEquals("Computer of employee was not as expected ", computer, computerRoundtrip);
+               Assert.assertEquals("Owner of computer was not as expected ", carloDeWolf, ownerOfComputer);
+
+               // Clean up the associations so we can remove
+               ownerOfComputer.setComputer(null);
+               computerRoundtrip.setOwner(null);
+
+               // Return
+               return null;
+            }
+
+         });
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+
+   }
+
+   /**
+    * Shows usage of the 1:N Unidirectional Mapping Between
+    * {@link Employee} and {@link Phone}
+    * @throws Throwable
+    */
+   @Test
+   public void oneToManyUnidirectionalMapping() throws Throwable
+   {
+      // Create an Employee
+      final Employee jaikiranPai = new Employee("Jaikiran Pai");
+
+      // Create a couple Phones
+      final Phone phone1 = new Phone();
+      phone1.setNumber("800-USE-JBOSS");
+      phone1.setType(PhoneType.WORK);
+      final Phone phone2 = new Phone();
+      phone2.setNumber("800-EJB-TIME");
+      phone2.setType(PhoneType.MOBILE);
+
+      try
+      {
+         // Persist and associate
+         final Long employeeId = txWrapper.wrapInTx(new Callable<Long>()
+         {
+
+            @Override
+            public Long call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(jaikiranPai);
+               em.persist(phone1);
+               em.persist(phone2);
+
+               // Associate 
+               jaikiranPai.getPhones().add(phone1);
+               jaikiranPai.getPhones().add(phone2);
+
+               // Return
+               return jaikiranPai.getId();
+            }
+         });
+
+         // Now check all was associated correctly
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get the EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the Employee
+               final Employee jaikiranRoundtrip = em.find(Employee.class, employeeId);
+
+               // Get Phones via the Employee
+               final Collection<Phone> phones = jaikiranRoundtrip.getPhones();
+               log.info("Phones for " + jaikiranRoundtrip + ": " + phones);
+
+               // Assert all's as expected
+               final String assertionError = "Phones were not associated with the employee as expected";
+               Assert.assertEquals(assertionError, 2, phones.size());
+               Assert.assertTrue(assertionError, phones.contains(phone1));
+               Assert.assertTrue(assertionError, phones.contains(phone2));
+
+               // Clean up the associations so we can remove things
+               jaikiranRoundtrip.getPhones().clear();
+
+               // Return
+               return null;
+            }
+
+         });
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+
+   }
+
+   /**
+    * Shows usage of the 1:N Bidirectional Mapping Between
+    * {@link Employee} and his/her reports {@link Employee}.  Also
+    * shows the Manager of an {@link Employee}.
+    * @throws Throwable
+    */
+   @Test
+   public void oneToManyBidirectionalMapping() throws Throwable
+   {
+      // Create a few Employees
+      final Employee alrubinger = new Employee("Andrew Lee Rubinger");
+      final Employee carloDeWolf = new Employee("Carlo de Wolf");
+      final Employee jaikiranPai = new Employee("Jaikiran Pai");
+      final Employee bigD = new Employee("Big D");
+
+      try
+      {
+         // Persist and associate
+         final Long managerId = txWrapper.wrapInTx(new Callable<Long>()
+         {
+
+            @Override
+            public Long call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(jaikiranPai);
+               em.persist(alrubinger);
+               em.persist(carloDeWolf);
+               em.persist(bigD);
+
+               // Associate *both* sides of the bidirectional relationship
+               final Collection<Employee> peonsOfD = bigD.getPeons();
+               peonsOfD.add(alrubinger);
+               peonsOfD.add(carloDeWolf);
+               peonsOfD.add(jaikiranPai);
+               alrubinger.setManager(bigD);
+               carloDeWolf.setManager(bigD);
+               jaikiranPai.setManager(bigD);
+
+               // Return
+               return bigD.getId();
+            }
+         });
+
+         // Let the last Tx flush everything out, so lookup again 
+         // and perform assertions
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get the EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the Employee/Manager
+               final Employee managerRoundtrip = em.find(Employee.class, managerId);
+
+               // Get the reports to the manager
+               final Collection<Employee> peonsForManager = managerRoundtrip.getPeons();
+               log.info("Reports of " + managerRoundtrip + ": " + peonsForManager);
+
+               // Assert all's as expected
+               final String assertionMessage = "The Employee Manager/Reports relationship was not as expected";
+               Assert.assertEquals(assertionMessage, 3, peonsForManager.size());
+               Assert.assertTrue(assertionMessage, peonsForManager.contains(alrubinger));
+               Assert.assertTrue(assertionMessage, peonsForManager.contains(carloDeWolf));
+               Assert.assertTrue(assertionMessage, peonsForManager.contains(jaikiranPai));
+               Assert.assertEquals(assertionMessage, bigD, alrubinger.getManager());
+               Assert.assertEquals(assertionMessage, bigD, carloDeWolf.getManager());
+               Assert.assertEquals(assertionMessage, bigD, jaikiranPai.getManager());
+
+               // Clean up the associations so we can remove things
+               for (final Employee peon : peonsForManager)
+               {
+                  peon.setManager(null);
+               }
+               peonsForManager.clear();
+
+               // Return
+               return null;
+            }
+
+         });
+
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+   }
+
+   /**
+    * Shows usage of the N:1 Unidirectional Mapping Between
+    * {@link Customer} and his/her primary {@link Employee} contact. 
+    * @throws Throwable
+    */
+   @Test
+   public void manyToOneUnidirectionalMapping() throws Throwable
+   {
+      // Create an Employee
+      final Employee bstansberry = new Employee("Brian Stansberry");
+
+      // Create a couple of Customers
+      final Customer jgreene = new Customer("Jason T. Greene");
+      final Customer bobmcw = new Customer("Bob McWhirter");
+
+      try
+      {
+         // Persist and associate
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(bstansberry);
+               em.persist(jgreene);
+               em.persist(bobmcw);
+
+               // Associate 
+               jgreene.setPrimaryContact(bstansberry);
+               bobmcw.setPrimaryContact(bstansberry);
+
+               // Return
+               return null;
+            }
+         });
+
+         // Lookup and perform assertions 
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the customers
+               final Customer jgreeneRoundtrip = em.find(Customer.class, jgreene.getId());
+               final Customer bobmcwRoundtrip = em.find(Customer.class, bobmcw.getId());
+
+               // Ensure all's as expected
+               final String assertionMessage = "Primary contact was not assigned as expected";
+               Assert.assertEquals(assertionMessage, bstansberry, jgreeneRoundtrip.getPrimaryContact());
+               Assert.assertEquals(assertionMessage, bstansberry, bobmcwRoundtrip.getPrimaryContact());
+
+               // Clean up the associations so we can remove things
+               jgreeneRoundtrip.setPrimaryContact(null);
+               bobmcwRoundtrip.setPrimaryContact(null);
+
+               // Return
+               return null;
+            }
+         });
+
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+   }
+
+   /**
+    * Shows usage of the N:N Unidirectional Mapping Between
+    * {@link Customer} and his/her assigned {@link Task}s 
+    * @throws Throwable
+    */
+   @Test
+   public void manyToManyUnidirectionalMapping() throws Throwable
+   {
+      // Create a couple of employees
+      final Employee smarlow = new Employee("Scott Marlow");
+      final Employee jpederse = new Employee("Jesper Pedersen");
+
+      // Create a couple of tasks
+      final Task task1 = new Task("Go to the JBoss User's Group - Boston");
+      final Task task2 = new Task("Pick up flowers for Shelly McGowan");
+
+      try
+      {
+         // Persist and associate
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(smarlow);
+               em.persist(jpederse);
+               em.persist(task1);
+               em.persist(task2);
+
+               // Associate 
+               task1.getOwners().add(smarlow);
+               task1.getOwners().add(jpederse);
+               task2.getOwners().add(smarlow);
+               task2.getOwners().add(jpederse);
+
+               // Return
+               return null;
+            }
+         });
+
+         // Lookup and perform assertions 
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the tasks
+               final Task task1Roundtrip = em.find(Task.class, task1.getId());
+               final Task task2Roundtrip = em.find(Task.class, task2.getId());
+
+               // Ensure all's as expected
+               final String assertionMessage = "Task owners were not assigned as expected";
+               Assert.assertTrue(assertionMessage, task1Roundtrip.getOwners().contains(smarlow));
+               Assert.assertTrue(assertionMessage, task1Roundtrip.getOwners().contains(jpederse));
+               Assert.assertTrue(assertionMessage, task2Roundtrip.getOwners().contains(smarlow));
+               Assert.assertTrue(assertionMessage, task2Roundtrip.getOwners().contains(jpederse));
+
+               // Clean up the associations so we can remove things
+               task1Roundtrip.getOwners().clear();
+               task2Roundtrip.getOwners().clear();
+
+               // Return
+               return null;
+            }
+         });
+
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+   }
+
+   /**
+    * Shows usage of the N:N Unidirectional Mapping Between
+    * {@link Employee} and his/her team members.
+    * @throws Throwable
+    */
+   @Test
+   public void manyToManyBidirectionalMapping() throws Throwable
+   {
+      // Create a few employees
+      final Employee pmuir = new Employee("Pete Muir");
+      final Employee dallen = new Employee("Dan Allen");
+      final Employee aslak = new Employee("Aslak Knutsen");
+
+      // Create some teams
+      final Team seam = new Team("Seam");
+      final Team arquillian = new Team("Arquillian");
+
+      try
+      {
+         // Persist and associate
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Persist
+               em.persist(pmuir);
+               em.persist(dallen);
+               em.persist(aslak);
+               em.persist(seam);
+               em.persist(arquillian);
+
+               // Associate *both* directions
+               seam.getMembers().add(dallen);
+               seam.getMembers().add(pmuir);
+               seam.getMembers().add(aslak);
+               arquillian.getMembers().add(dallen);
+               arquillian.getMembers().add(pmuir);
+               arquillian.getMembers().add(aslak);
+               aslak.getTeams().add(seam);
+               aslak.getTeams().add(arquillian);
+               dallen.getTeams().add(seam);
+               dallen.getTeams().add(arquillian);
+               pmuir.getTeams().add(seam);
+               pmuir.getTeams().add(arquillian);
+
+               // Return
+               return null;
+            }
+         });
+
+         // Lookup and perform assertions 
+         txWrapper.wrapInTx(new Callable<Void>()
+         {
+
+            @Override
+            public Void call() throws Exception
+            {
+               // Get EM
+               final EntityManager em = emHook.getEntityManager();
+
+               // Get the teams and employees back out as managed objects
+               final Team seamRoundtrip = em.find(Team.class, seam.getId());
+               final Team arquillianRoundtrip = em.find(Team.class, arquillian.getId());
+               final Employee dallenRoundtrip = em.find(Employee.class, dallen.getId());
+               final Employee pmuirRoundtrip = em.find(Employee.class, pmuir.getId());
+               final Employee aslakRoundtrip = em.find(Employee.class, aslak.getId());
+
+               // Ensure all's as expected
+               final String assertionMessage = "Team members were not assigned as expected";
+               Assert.assertTrue(assertionMessage, seamRoundtrip.getMembers().contains(pmuir));
+               Assert.assertTrue(assertionMessage, seamRoundtrip.getMembers().contains(aslak));
+               Assert.assertTrue(assertionMessage, seamRoundtrip.getMembers().contains(dallen));
+               Assert.assertTrue(assertionMessage, arquillianRoundtrip.getMembers().contains(pmuir));
+               Assert.assertTrue(assertionMessage, arquillianRoundtrip.getMembers().contains(aslak));
+               Assert.assertTrue(assertionMessage, arquillianRoundtrip.getMembers().contains(dallen));
+               Assert.assertTrue(assertionMessage, dallenRoundtrip.getTeams().contains(seamRoundtrip));
+               Assert.assertTrue(assertionMessage, dallenRoundtrip.getTeams().contains(arquillianRoundtrip));
+               Assert.assertTrue(assertionMessage, pmuirRoundtrip.getTeams().contains(seamRoundtrip));
+               Assert.assertTrue(assertionMessage, pmuirRoundtrip.getTeams().contains(arquillianRoundtrip));
+               Assert.assertTrue(assertionMessage, aslakRoundtrip.getTeams().contains(seamRoundtrip));
+               Assert.assertTrue(assertionMessage, aslakRoundtrip.getTeams().contains(arquillianRoundtrip));
+
+               // Clean up the associations so we can remove things
+               aslakRoundtrip.getTeams().clear();
+               dallenRoundtrip.getTeams().clear();
+               pmuirRoundtrip.getTeams().clear();
+               seamRoundtrip.getMembers().clear();
+               arquillianRoundtrip.getMembers().clear();
+
+               // Return
+               return null;
+            }
+         });
+
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap
+         throw tee.getCause();
+      }
+   }
+
    //-------------------------------------------------------------------------------------||
    // Internal Helper Methods -----------------------------------------------------------||
    //-------------------------------------------------------------------------------------||

Modified: projects/ejb-book/trunk/testsupport/src/main/java/org/jboss/ejb3/examples/testsupport/entity/AutogenIdentityBase.java
===================================================================
--- projects/ejb-book/trunk/testsupport/src/main/java/org/jboss/ejb3/examples/testsupport/entity/AutogenIdentityBase.java	2010-05-20 20:26:39 UTC (rev 105076)
+++ projects/ejb-book/trunk/testsupport/src/main/java/org/jboss/ejb3/examples/testsupport/entity/AutogenIdentityBase.java	2010-05-20 20:29:53 UTC (rev 105077)
@@ -68,4 +68,49 @@
       this.id = id;
    }
 
+   //-------------------------------------------------------------------------------------||
+   // Overridden Implementations ---------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /*
+    * Value equality is based by ID only
+    */
+
+   /**
+    * {@inheritDoc}
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode()
+   {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((id == null) ? 0 : id.hashCode());
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null)
+         return false;
+      if (getClass() != obj.getClass())
+         return false;
+      AutogenIdentityBase other = (AutogenIdentityBase) obj;
+      if (id == null)
+      {
+         if (other.id != null)
+            return false;
+      }
+      else if (!id.equals(other.id))
+         return false;
+      return true;
+   }
+
 }




More information about the jboss-cvs-commits mailing list