Merge with Parent/Child entities not possible

#1

Can you please tell me why the following unit test ends with "[ObjectDB 2.5.7_02] javax.persistence.RollbackException"?

package example;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.FetchType;
import javax.persistence.FlushModeType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class ObjectDbMergeTest {

@Entity
public static class ParentEntity {
  @Id
  @GeneratedValue
  private long id;

  @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "parent", orphanRemoval = true)
  @MapKey(name = "childName")
  private Map<String, ChildEntity> children = new HashMap<String, ChildEntity>();

  public Map<String, ChildEntity> getChildren() {
   return children;
  }

  public void addChild(ChildEntity child) {
   child.setParent(this);
   children.put(child.getChildName(), child);
  }

  public long getId() {
   return id;
  }

  public void setId(long id) {
   this.id = id;
  }
}

@Entity
public static class ChildEntity {

  @Id
  @GeneratedValue
  private long id;

  @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
  private ParentEntity parent;

  @Column
  private String childName;

  public ChildEntity() {
  }

  public ChildEntity withChildName(String value) {
   childName = value;
   return this;
  }

  public ParentEntity getParent() {
   return parent;
  }

  public void setParent(ParentEntity parent) {
   this.parent = parent;
  }

  public String getChildName() {
   return childName;
  }

  public void setChildName(String childName) {
   this.childName = childName;
  }

  public long getId() {
   return id;
  }

  public void setId(long id) {
   this.id = id;
  }
}

private EntityManager createEntityManager(String dbFileName, boolean delete) {

  EntityManagerFactory emf = null;
  if (delete) {
   new File(dbFileName).delete();
   new File(dbFileName + "$").delete();
  }
  emf = Persistence.createEntityManagerFactory("objectdb:" + dbFileName);

  EntityManager entityManager = emf.createEntityManager();
  entityManager.setFlushMode(FlushModeType.AUTO);

  return entityManager;
}

private void closeEntityManager(EntityManager entityManager) {
  if (entityManager != null && entityManager.isOpen()) {
   entityManager.close();
   entityManager.getEntityManagerFactory().close();
  }
}

private EntityManager entityManager;

@Before
public void setUp() throws Exception {
  entityManager = createEntityManager("d:\\Temp\\MergeTest.odb", true);

  ParentEntity parentEntity = new ParentEntity();
  entityManager.getTransaction().begin();
  entityManager.persist(parentEntity);
  parentEntity.addChild(new ChildEntity().withChildName("childEntity1"));
  parentEntity.addChild(new ChildEntity().withChildName("childEntity2"));
  parentEntity.addChild(new ChildEntity().withChildName("childEntity3"));
  parentEntity.addChild(new ChildEntity().withChildName("childEntity4"));
  entityManager.getTransaction().commit();
}

@After
public void tearDown() throws Exception {
  closeEntityManager(entityManager);
}

@Test
public void test() {
  TypedQuery<ParentEntity> parentEntityQuery = entityManager.createQuery("Select p from ParentEntity p",
    ParentEntity.class);
  ParentEntity parentEntity = parentEntityQuery.getSingleResult();
  entityManager.refresh(parentEntity);
  Assert.assertEquals(4, parentEntity.getChildren().size());

  entityManager.getTransaction().begin();
  ParentEntity parentEntityNew = new ParentEntity();
  parentEntityNew.setId(parentEntity.getId());
  parentEntityNew.addChild(new ChildEntity().withChildName("childEntity4"));
  parentEntity = entityManager.merge(parentEntityNew);
  entityManager.getTransaction().commit();

  entityManager.refresh(parentEntity);
  Assert.assertEquals(1, parentEntity.getChildren().size());
}
}

 

 

#2

This seems to be an old issue. The test passes with build 2.6.0_01.

ObjectDB Support

Reply