Program: 66276
Project: 66276
Buggy source:
@Test public void simpleSerializeAndMerge() throws Exception {
  EntityManager em=createEntityManager();
  int id=minEmployeeIdWithAddressAndPhones(em);
  HashMap<String,PhoneNumber> phonesOriginal=new HashMap();
  Employee empOriginal=em.find(Employee.class,id);
  for (  PhoneNumber phone : empOriginal.getPhoneNumbers()) {
    phonesOriginal.put(phone.getType(),phone);
  }
  closeEntityManager(em);
  clearCache();
  int newSalary=empOriginal.getSalary() * 2;
  if (newSalary == 0) {
    newSalary=100;
  }
  em=createEntityManager();
  Query query=em.createQuery("String_Node_Str" + id);
  FetchGroup fetchGroup=new FetchGroup("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.setShouldLoad(true);
  query.setHint(QueryHints.FETCH_GROUP,fetchGroup);
  Employee emp=(Employee)query.getSingleResult();
  Employee empSerialized;
  Employee empDeserialized;
  Employee empMerged;
  beginTransaction(em);
  try {
    empSerialized=serialize(emp);
    assertFetched(empSerialized,fetchGroup);
    empSerialized.setFirstName("String_Node_Str");
    empSerialized.setLastName("String_Node_Str");
    empSerialized.setSalary(newSalary);
    FetchGroup extendedFetchGroup=(FetchGroup)fetchGroup.clone();
    extendedFetchGroup.addAttribute("String_Node_Str");
    assertFetched(empSerialized,extendedFetchGroup);
    empSerialized.getAddress().setCountry("String_Node_Str");
    assertFetched(empSerialized.getAddress(),fetchGroup.getGroup("String_Node_Str"));
    empSerialized.getAddress().setCity("String_Node_Str");
    extendedFetchGroup.addAttribute("String_Node_Str");
    assertFetched(empSerialized.getAddress(),extendedFetchGroup.getGroup("String_Node_Str"));
    extendedFetchGroup.addAttribute("String_Node_Str");
    for (    PhoneNumber phone : empSerialized.getPhoneNumbers()) {
      phone.setAreaCode("String_Node_Str");
      assertFetched(phone,fetchGroup.getGroup("String_Node_Str"));
      phone.setNumber("String_Node_Str");
      assertFetched(phone,extendedFetchGroup.getGroup("String_Node_Str"));
    }
    empDeserialized=serialize(empSerialized);
    assertFetched(empDeserialized,extendedFetchGroup);
    assertFetched(empDeserialized.getAddress(),extendedFetchGroup.getGroup("String_Node_Str"));
    for (    PhoneNumber phone : empDeserialized.getPhoneNumbers()) {
      assertFetched(phone,extendedFetchGroup.getGroup("String_Node_Str"));
    }
    empMerged=em.merge(empDeserialized);
    assertEquals("String_Node_Str",empMerged.getFirstName());
    assertEquals("String_Node_Str",empMerged.getLastName());
    assertEquals(newSalary,empMerged.getSalary());
    assertEquals("String_Node_Str",empMerged.getAddress().getCountry());
    assertEquals("String_Node_Str",empMerged.getAddress().getCity());
    for (    PhoneNumber phone : empSerialized.getPhoneNumbers()) {
      assertEquals("String_Node_Str",phone.getAreaCode());
      assertEquals("String_Node_Str",phone.getNumber());
    }
    assertEquals(empOriginal.getGender(),empMerged.getGender());
    if (empOriginal.getDepartment() != null) {
      assertEquals(empOriginal.getDepartment().getId(),empMerged.getDepartment().getId());
    }
    if (empOriginal.getPeriod() != null) {
      assertEquals(empOriginal.getPeriod().getStartDate(),empMerged.getPeriod().getStartDate());
      assertEquals(empOriginal.getPeriod().getEndDate(),empMerged.getPeriod().getEndDate());
    }
    assertEquals(empOriginal.getPayScale(),empMerged.getPayScale());
    assertEquals(empOriginal.getStartTime(),empMerged.getStartTime());
    assertEquals(empOriginal.getEndTime(),empMerged.getEndTime());
    commitTransaction(em);
  }
  finally {
    if (isTransactionActive(em)) {
      rollbackTransaction(em);
    }
  }
  em.clear();
  HashMap hints=new HashMap(2);
  hints.put(QueryHints.CACHE_USAGE,CacheUsage.CheckCacheOnly);
  Employee empShared=em.find(Employee.class,id,hints);
  assertEquals("String_Node_Str",empShared.getFirstName());
  assertEquals("String_Node_Str",empShared.getLastName());
  assertEquals(newSalary,empShared.getSalary());
  assertEquals("String_Node_Str",empShared.getAddress().getCountry());
  assertEquals("String_Node_Str",empShared.getAddress().getCity());
  for (  PhoneNumber phone : empShared.getPhoneNumbers()) {
    assertEquals("String_Node_Str",phone.getAreaCode());
    assertEquals("String_Node_Str",phone.getNumber());
  }
  clearCache();
  em.clear();
  Employee empDb=em.find(Employee.class,id);
  assertEquals("String_Node_Str",empDb.getFirstName());
  assertEquals("String_Node_Str",empDb.getLastName());
  assertEquals(newSalary,empDb.getSalary());
  assertEquals("String_Node_Str",empDb.getAddress().getCountry());
  assertEquals("String_Node_Str",empDb.getAddress().getCity());
  for (  PhoneNumber phone : empDb.getPhoneNumbers()) {
    assertEquals("String_Node_Str",phone.getAreaCode());
    assertEquals("String_Node_Str",phone.getNumber());
  }
  beginTransaction(em);
  try {
    empDb.setFirstName(empOriginal.getFirstName());
    empDb.setLastName(empOriginal.getLastName());
    empDb.setSalary(empOriginal.getSalary());
    empDb.getAddress().setCountry(empOriginal.getAddress().getCountry());
    empDb.getAddress().setCity(empOriginal.getAddress().getCity());
    for (    PhoneNumber phone : empDb.getPhoneNumbers()) {
      PhoneNumber phoneOriginal=phonesOriginal.get(phone.getType());
      phone.setAreaCode(phoneOriginal.getAreaCode());
      phone.setNumber(phoneOriginal.getNumber());
    }
    commitTransaction(em);
  }
  finally {
    if (isTransactionActive(em)) {
      rollbackTransaction(em);
    }
    closeEntityManager(em);
  }
}

Fixed version (ground truth):
@Test public void simpleSerializeAndMerge() throws Exception {
  EntityManager em=createEntityManager();
  int id=minEmployeeIdWithAddressAndPhones(em);
  HashMap<String,PhoneNumber> phonesOriginal=new HashMap();
  Employee empOriginal=em.find(Employee.class,id);
  for (  PhoneNumber phone : empOriginal.getPhoneNumbers()) {
    phonesOriginal.put(phone.getType(),phone);
  }
  closeEntityManager(em);
  clearCache();
  int newSalary=empOriginal.getSalary() * 2;
  if (newSalary == 0) {
    newSalary=100;
  }
  em=createEntityManager();
  beginTransaction(em);
  Query query=em.createQuery("String_Node_Str" + id);
  FetchGroup fetchGroup=new FetchGroup("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.addAttribute("String_Node_Str");
  fetchGroup.setShouldLoad(true);
  query.setHint(QueryHints.FETCH_GROUP,fetchGroup);
  Employee emp=(Employee)query.getSingleResult();
  Employee empSerialized;
  Employee empDeserialized;
  Employee empMerged;
  try {
    empSerialized=serialize(emp);
    assertFetched(empSerialized,fetchGroup);
    empSerialized.setFirstName("String_Node_Str");
    empSerialized.setLastName("String_Node_Str");
    empSerialized.setSalary(newSalary);
    FetchGroup extendedFetchGroup=(FetchGroup)fetchGroup.clone();
    extendedFetchGroup.addAttribute("String_Node_Str");
    assertFetched(empSerialized,extendedFetchGroup);
    empSerialized.getAddress().setCountry("String_Node_Str");
    assertFetched(empSerialized.getAddress(),fetchGroup.getGroup("String_Node_Str"));
    empSerialized.getAddress().setCity("String_Node_Str");
    extendedFetchGroup.addAttribute("String_Node_Str");
    assertFetched(empSerialized.getAddress(),extendedFetchGroup.getGroup("String_Node_Str"));
    extendedFetchGroup.addAttribute("String_Node_Str");
    for (    PhoneNumber phone : empSerialized.getPhoneNumbers()) {
      phone.setAreaCode("String_Node_Str");
      assertFetched(phone,fetchGroup.getGroup("String_Node_Str"));
      phone.setNumber("String_Node_Str");
      assertFetched(phone,extendedFetchGroup.getGroup("String_Node_Str"));
    }
    empDeserialized=serialize(empSerialized);
    assertFetched(empDeserialized,extendedFetchGroup);
    assertFetched(empDeserialized.getAddress(),extendedFetchGroup.getGroup("String_Node_Str"));
    for (    PhoneNumber phone : empDeserialized.getPhoneNumbers()) {
      assertFetched(phone,extendedFetchGroup.getGroup("String_Node_Str"));
    }
    empMerged=em.merge(empDeserialized);
    assertEquals("String_Node_Str",empMerged.getFirstName());
    assertEquals("String_Node_Str",empMerged.getLastName());
    assertEquals(newSalary,empMerged.getSalary());
    assertEquals("String_Node_Str",empMerged.getAddress().getCountry());
    assertEquals("String_Node_Str",empMerged.getAddress().getCity());
    for (    PhoneNumber phone : empSerialized.getPhoneNumbers()) {
      assertEquals("String_Node_Str",phone.getAreaCode());
      assertEquals("String_Node_Str",phone.getNumber());
    }
    assertEquals(empOriginal.getGender(),empMerged.getGender());
    if (empOriginal.getDepartment() != null) {
      assertEquals(empOriginal.getDepartment().getId(),empMerged.getDepartment().getId());
    }
    if (empOriginal.getPeriod() != null) {
      assertEquals(empOriginal.getPeriod().getStartDate(),empMerged.getPeriod().getStartDate());
      assertEquals(empOriginal.getPeriod().getEndDate(),empMerged.getPeriod().getEndDate());
    }
    assertEquals(empOriginal.getPayScale(),empMerged.getPayScale());
    assertEquals(empOriginal.getStartTime(),empMerged.getStartTime());
    assertEquals(empOriginal.getEndTime(),empMerged.getEndTime());
    commitTransaction(em);
  }
  finally {
    if (isTransactionActive(em)) {
      rollbackTransaction(em);
    }
  }
  em.clear();
  HashMap hints=new HashMap(2);
  hints.put(QueryHints.CACHE_USAGE,CacheUsage.CheckCacheOnly);
  Employee empShared=em.find(Employee.class,id,hints);
  assertEquals("String_Node_Str",empShared.getFirstName());
  assertEquals("String_Node_Str",empShared.getLastName());
  assertEquals(newSalary,empShared.getSalary());
  assertEquals("String_Node_Str",empShared.getAddress().getCountry());
  assertEquals("String_Node_Str",empShared.getAddress().getCity());
  for (  PhoneNumber phone : empShared.getPhoneNumbers()) {
    assertEquals("String_Node_Str",phone.getAreaCode());
    assertEquals("String_Node_Str",phone.getNumber());
  }
  clearCache();
  em.clear();
  Employee empDb=em.find(Employee.class,id);
  assertEquals("String_Node_Str",empDb.getFirstName());
  assertEquals("String_Node_Str",empDb.getLastName());
  assertEquals(newSalary,empDb.getSalary());
  assertEquals("String_Node_Str",empDb.getAddress().getCountry());
  assertEquals("String_Node_Str",empDb.getAddress().getCity());
  for (  PhoneNumber phone : empDb.getPhoneNumbers()) {
    assertEquals("String_Node_Str",phone.getAreaCode());
    assertEquals("String_Node_Str",phone.getNumber());
  }
  beginTransaction(em);
  try {
    empDb.setFirstName(empOriginal.getFirstName());
    empDb.setLastName(empOriginal.getLastName());
    empDb.setSalary(empOriginal.getSalary());
    empDb.getAddress().setCountry(empOriginal.getAddress().getCountry());
    empDb.getAddress().setCity(empOriginal.getAddress().getCity());
    for (    PhoneNumber phone : empDb.getPhoneNumbers()) {
      PhoneNumber phoneOriginal=phonesOriginal.get(phone.getType());
      phone.setAreaCode(phoneOriginal.getAreaCode());
      phone.setNumber(phoneOriginal.getNumber());
    }
    commitTransaction(em);
  }
  finally {
    if (isTransactionActive(em)) {
      rollbackTransaction(em);
    }
    closeEntityManager(em);
  }
}