Mysterious "Attempt to persist a reference to a non managed instance" error

#1

I've been working with ObjectDB for the past several months, and it's behaved pretty much as expected. I made a few modifications to a working set of classes today, and it's started throwing exceptions at commit time. I've stripped it down to a  set of files that seem to be of trivial complexity, but it's still failing.

It involves two entities, Index and Ostrich. The thing to note is that the Index structure is recursive through maps; but that's never caused any problem for me in the past.

package failing;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity public class Ostrich implements Serializable {
    @Id long id;
    public Ostrich() { }
}
package failing;
import java.io.Serializable;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import static javax.persistence.CascadeType.*;
import static javax.persistence.FetchType.*;

@Entity public class Index implements Serializable {
    @Id @GeneratedValue private long id;
    @OneToOne(fetch=EAGER, cascade=PERSIST) public Ostrich ostrich;
    @ManyToMany(cascade=ALL) public Map<String, Index> entries;

    public Index(Ostrich ostrich, Map<String, Index> entries) {
      this.entries = entries;
      this.ostrich = ostrich;
    }

   @SuppressWarnings("unused") private Index() { }

   public Ostrich getOstrich() { return ostrich; }
}

...and a program to try it out:

package failing;
import java.util.HashMap;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import com.objectdb.Enhancer;

public class ODBTest {

  public static void main(String[] args) {
      Enhancer.enhance("failing.*");
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("./db/db0.odb");
      EntityManager em = emf.createEntityManager();
 
      Ostrich oo = new Ostrich();
      Index dd = new Index(oo, new HashMap<String, Index>());
 
      HashMap<String, Index> dEntries = new HashMap<String, Index>();
      dEntries.put("xxx", dd);
 
      Ostrich o = new Ostrich();
      Index d = new Index(o, dEntries);
 
      EntityTransaction tx = em.getTransaction();
      tx.begin();
 
      em.persist(d);
      em.persist(dd);
      em.persist(o);
      em.persist(oo);
 
      tx.commit();
    }
}

I had started with the expectation that the cascading annotations would be sufficient to cause everything to be persisted (and that's worked well for me in the past), but no cigars. So, you'll note that all four of the entities (2 Index, 2 Ostrich) that the test program allocated are now explicitly persisted in the transaction---and I'm still getting an exception:

Exception in thread "main" [ObjectDB 2.2.6_03] javax.persistence.RollbackException
Failed to commit transaction: Attempt to persist a reference to a non managed failing.Ostrich instance (error 613)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:277)
at failing.ODBTest.main(ODBTest.java:38)
Caused by: javax.persistence.PersistenceException: com.objectdb.o.UserException: Attempt to persist a reference to a non managed failing.Ostrich instance
at com.objectdb.o._PersistenceException.b(_PersistenceException.java:47)
at com.objectdb.o.JPE.g(JPE.java:140)
at com.objectdb.o.JPE.g(JPE.java:78)
... 4 more
Caused by: com.objectdb.o.UserException: Attempt to persist a reference to a non managed failing.Ostrich instance
at com.objectdb.o.MSG.d(MSG.java:61)
at com.objectdb.o.TYW.writeElement(TYW.java:246)
at failing.Index.__odbWriteContent(Index.java:1)
at com.objectdb.o.MMM.af(MMM.java:1025)
at com.objectdb.o.UTY.aF(UTY.java:1185)
at com.objectdb.o.UTY.aE(UTY.java:1174)
at com.objectdb.o.ENH.a(ENH.java:46)
at com.objectdb.o.STA.T(STA.java:512)
at com.objectdb.o.STM.D(STM.java:408)
at com.objectdb.o.OBM.bH(OBM.java:884)
at com.objectdb.jdo.PMImpl.bH(PMImpl.java:2186)
at com.objectdb.o.OBM.bG(OBM.java:800)
at com.objectdb.o.OBM.bE(OBM.java:715)
at com.objectdb.jpa.EMImpl.commit(EMImpl.java:274)
... 1 more

Any clues as to what's going on here? This is so insanely simple, I must be missing something really basic.

#2

Thank you for this report and test case.

Please try build 2.2.6_04 that should fix this issue.

ObjectDB Support
#3

Code that was used for the fix had to be changed in build 2.2.8_06 because it causes some other problems.

If as a result of this the problems happens again - please report.

ObjectDB Support
#4

It is still happening for many to many relationship.... 

Failed to commit transaction: Attempt to persist a reference to a non managed jpa_beans.TicketNumbers instance

#5

Sorry for the wrong answer:

Here is the final sample:-

Bus.class

@ManyToMany(cascade = {CascadeType.ALL}, targetEntity = Passenger.class, mappedBy = "buses")

  private Set<Passenger> passengers= new HashSet();

 

Passenger.class

@ManyToMany(cascade = { CascadeType.ALL }, targetEntity = Bus.class)
    private List<Bus> buses= new ArrayList();

Reply