Index: src/test/org/datanucleus/tests/AttachDetachTest.java
===================================================================
--- src/test/org/datanucleus/tests/AttachDetachTest.java	(revision 9526)
+++ src/test/org/datanucleus/tests/AttachDetachTest.java	(working copy)
@@ -3844,6 +3844,127 @@
     }
 
     /**
+     * Tests the detach of a graph where a single object is encountered more than once,
+     * in different fetch plan states each time; the single detached object should contain a union
+     * of the required fields from each.
+     */
+    public void testDetachDuplicatesUnion()
+    {
+        try
+        {
+            // Setup a small company with a single manager and a few subordinates
+            PersistenceManager pm = pmf.getPersistenceManager();
+            Transaction tx = pm.currentTransaction();
+
+            try
+            {
+                tx.begin();
+
+                long id = 0;
+                Manager manager = new Manager(++id, "John", "Smith", "manager@globocorp.com", 200.0f, "1000");
+                for (int i = 1; i <= 5; ++i)
+                {
+                    Employee e = new Employee(++id, "First_" + i, "Second_" + i, "employee" + i + "@globocorp.com", 100.0f, Integer
+                            .toString(2000 + i), Integer.valueOf(i));
+
+                    e.setManager(manager);
+                    manager.addSubordinate(e);
+                }
+
+                pm.makePersistent(manager);
+
+                tx.commit();
+            }
+            catch (Exception e)
+            {
+                LOG.error(e);
+                fail("Exception thrown while creating test data" + e.getMessage());
+                return;
+            }
+            finally
+            {
+                if (tx.isActive())
+                {
+                    tx.rollback();
+                }
+                pm.close();
+            }
+
+            pm = pmf.getPersistenceManager();
+            tx = pm.currentTransaction();
+
+            Object[] detached;
+            try
+            {
+                tx.begin();
+
+                // Include salary, manager, serialNo fields
+                pm.getFetchPlan().addGroup("groupA");
+
+                Query q = pm.newQuery(Employee.class);
+
+                // Ensure the manager is at the end of the return result
+                q.setOrdering("salary ASCENDING");
+
+                Collection<Employee> results = (Collection<Employee>)q.execute();
+
+                detached = pm.detachCopyAll(results).toArray();
+
+                tx.commit();
+            }
+            catch (Exception e)
+            {
+                LOG.error(e);
+                fail("Exception thrown while reading test data" + e.getMessage());
+                return;
+            }
+            finally
+            {
+                if (tx.isActive())
+                {
+                    tx.rollback();
+                }
+                pm.close();
+            }
+
+            try
+            {
+                // The last item in the collection should be the manager. 
+                int last = detached.length - 1;
+                Manager m = (Manager)detached[last];
+
+                // The manager is encountered in the object graph at fetch depth 0 (from the query),
+                // but also at fetch depth 1 (once for each subordinate). If the union was not calculated
+                // properly, fields may be missing that should have been fetched
+                assertEquals(200.0f, m.getSalary());
+                assertEquals("1000", m.getSerialNo());
+                assertNull(m.getManager());
+
+                // Check the same object (and not a duplicate) appears as the subordinates' manager
+                for (int i = 0; i < last; ++i)
+                {
+                    Employee e = (Employee)detached[i];
+                    assertSame("Employee's manager is duplicate", m, e.getManager());
+                }
+            }
+            catch (JDODetachedFieldAccessException e)
+            {
+                fail("detachCopy failed to fetch all the fields implied by the fetch plan");
+            }
+            catch (Exception e)
+            {
+                LOG.error(e);
+                fail("Exception thrown while reading test data" + e.getMessage());
+            }
+        }
+        finally
+        {
+            // Clean out our data
+            CompanyHelper.clearCompanyData(pmf);
+        }
+    }
+
+    /**
      * Test the specification of maximum fetch depth.
      */
     public void testMaxFetchDepth()

