ObjectDB ObjectDB

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;
  }
}
}

 

edit
delete
#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
edit
delete
#3

Hello,

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

edit
delete
#4

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

ObjectDB Support
edit
delete

Reply

To post on this website please sign in.