Issue #1602: Remove of an entry from a @OneToMany collection is not possible if the enhancer is disabled

Type: Bug ReoprtPriority: NormalStatus: FixedReplies: 3
#1

Hello!

When the JPA entities are not enhanced the removal of an entry from a @OneToMany collection is not possible. The following java code demonstrates the problem. The statement

parentEntity.getChildEntityContainer().remove("01");

does not work correctly with not enhanced JPA entities.

package objectdb.examples;

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.OneToMany;
import javax.persistence.Persistence;

import org.junit.Assert;

public final class ChildEntityRemoveProblem {


public static void main(String[] args) {
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("objectdb:$objectdb/db/test.tmp;drop");
  EntityManager entityManager = emf.createEntityManager();

  ParentEntity parentEntity = new ParentEntity();
  entityManager.getTransaction().begin();
  entityManager.persist(parentEntity);
  entityManager.getTransaction().commit();


  entityManager.getTransaction().begin();
  ChildEntity childEntity = new ChildEntity();
  childEntity.setStringAttribute1("abc");
  parentEntity.getChildEntityContainer().put("01", childEntity);
  entityManager.flush();

  entityManager.remove(parentEntity.getChildEntityContainer().get("01"));
  parentEntity.getChildEntityContainer().remove("01");
  entityManager.flush();

  entityManager.getTransaction().commit();

  entityManager.clear();

  parentEntity = entityManager.find(ParentEntity.class, 1l);
  Assert.assertEquals(0, parentEntity.getChildEntityContainer().size());

  entityManager.close();
  emf.close();
}


@Entity
public static class ChildEntity {

  @Column
  private String stringAttribute1;

  public String getStringAttribute1() {
   return stringAttribute1;
  }

  public void setStringAttribute1(String stringAttribute1) {
   this.stringAttribute1 = stringAttribute1;
  }
}

@Entity
public static class ParentEntity {

  @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
  private Map<String, ChildEntity> childEntityContainer = new HashMap<String, ChildEntityRemoveProblem.ChildEntity>();


  public Map<String, ChildEntity> getChildEntityContainer() {
   return childEntityContainer;
  }
}
}

 

#2

Thank you for this report. It represents an issue with non enhanced classes, but it is not related to @OneToMany collection. Any change to entity objects after flush is not detected, as demonstrated by a simpler test case that also fails:

import javax.persistence.*;

import org.junit.Assert;

public final class T1602b {

    public static void main(String[] args) {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb:$objectdb/db/test.tmp;drop");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        MyEntity e = new MyEntity();
        em.persist(e);
        em.getTransaction().commit();

        em.getTransaction().begin();
        e.x = 1;
        em.flush();

        e.x = 2; // not detected if class is not enhanced
        em.flush();
       
        em.getTransaction().commit();
        em.clear();

        e = em.find(MyEntity.class, 1l);
        Assert.assertEquals(2, e.x);

        em.close();
        emf.close();
    }

    @Entity
    public static class MyEntity {
        int x;
    }
}

Build 2.6.0_04 includes a fix of this issue.

ObjectDB Support
#3

Hello,

I have tried version 2.6.0_04. The problem with the @OneToMany collection is still not fixed.

#4

You are right, sorry. Somehow the fix has not been integrated into that build. Please try build 2.6.1.

ObjectDB Support

Reply