複数の同一型の子Entityを持つ親を取得すると、全ての子Entityが同じになる。

前回のエントリの続き


以下実験ソース。コミュニティにも投げてみたけど・・・
(つい誤字というか余計な引用まで入れてしまったorz)

Employeeと、contactInfoはサンプルより流用して修正
テストの親クラスはまんま流用

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Employee {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   private Long id;

   @Persistent
   private ContactInfo myContactInfo;
   @Persistent
   private ContactInfo officeContactInfo;
//setter/getter
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class ContactInfo {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   private Key key;

   @Persistent
   private String streetAddress;

   @Persistent
   private String city;

   @Persistent
   private String stateOrProvince;

   @Persistent
   private String zipCode;
//setter/getter
}
public class EmployeeTest extends LocalDatastoreTestCase {
       public void testEmployeeFind() {
           Employee e = new Employee();

           ContactInfo ci = new ContactInfo();
           ci.setZipCode("1111");
           e.setMyContactInfo(ci);

           ContactInfo office = new ContactInfo();
           office.setZipCode("2222");
           e.setOfficeContactInfo(office);

           Transaction tx = pm.currentTransaction();
           try {
               tx.begin();
               pm.makePersistent(e);
               tx.commit();
           } finally {
               if (tx.isActive()) {
                   tx.rollback();
               }
           }

               Query query = pm.newQuery(Employee.class);
               query.setRange(0, 1);
               List<Employee> results = (List<Employee>) query.execute();
               if(results.size() > 0) {
                       Employee target = results.get(0);
                       assertNotSame(target.getMyContactInfo(), target.getOfficeContactInfo());//ここで失敗
                       assertEquals("1111", target.getMyContactInfo().getZipCode());
                       assertEquals("2222", target.getOfficeContactInfo().getZipCode());
               } else {
                       fail();
               }

       }


       PersistenceManagerFactory factory;
       PersistenceManager pm;

       @Override
       public void tearDown() throws Exception {
               super.tearDown();
               if(!pm.isClosed()) {
                       pm.close();
               }
       }

       @Override
       public void setUp() throws Exception {
               super.setUp();
               factory = JDOHelper.getPersistenceManagerFactory("transactions-optional");
               pm = factory.getPersistenceManager();
       }
}


ちなみに、子を埋め込み(@Embedded)とすると大丈夫なんだけど・・・
いや・・・まぁ実際問題今回は実害が出ないけど、なんか気持ち悪いなぁ