Issue #1976: Schema-Update: Rename superclass and remove one subclass

Type: Bug ReoprtVersion: 2.6.9Priority: NormalStatus: ActiveReplies: 2
#1

Hello,

we renamed a superclass and removed one of the subclass.

If we then try to open the Database (with ObjectDB-Explorer) we get a "Failed to generate dynamic type ..."

 

Small Example:

Generate Database

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

  // // Persist an entity
  em.getTransaction().begin();
  ChildClassA entity1 = new ChildClassA();
  entity1.kind = "kindA";
  entity1.mode = "modeB";
  em.persist(entity1);
  ChildClassA entity2 = new ChildClassA();
  entity2.kind = "kindC";
  entity2.mode = "modeD";
  em.persist(entity2);
  ChildClassB entity3 = new ChildClassB();
  entity3.onlyRecordLastStep = false;
  em.persist(entity3);
  em.getTransaction().commit();

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

Entities:

@Entity
@Access(AccessType.FIELD)
public class SuperClass {

  public SuperClass() {
  }
}

ChildClassA:

@Entity
@Access(AccessType.FIELD)
public class ChildClassA extends SuperClass {

@Basic public String kind;

@Basic public String mode;

  protected ChildClassA() {
  }
}

ChildClassB:

@Entity
@Access(AccessType.FIELD)
public class ChildClassB extends SuperClass {

@Basic
public boolean onlyRecordLastStep = false;

  protected ChildClassB() {
  }
}

 

Then we rename SuperClass to RenamedSuperClass and Remove the ChildClassB.

<schema>
    <package name="schemaupdate.delete">
         <class name="SuperClass" new-name="RenamedSuperClass" />
    </package>
</schema>

 

@Entity
@Access(AccessType.FIELD)
public class RenamedSuperClass {

  public RenamedSuperClass() {
  }
}

 

@Entity
@Access(AccessType.FIELD)
public class ChildClassA extends RenamedSuperClass {

@Basic public String kind;

@Basic public String mode;

  protected ChildClassA() {
  }
}

And then we access the prevous create Database with the following example:

public static void main(String[] args) {

  // no drop - reuse the existing file
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("objectdb:test.tmp");
  EntityManager em = emf.createEntityManager();

  // don't create a new objects!
  // access the existing

  emf.getMetamodel().entity(RenamedSuperClass.class);

  em.getTransaction().begin();
  // do something
  ChildClassA entityWithID1 = em.find(ChildClassA.class, 1);
  entityWithID1.mode = "a";
  ChildClassA entityWithID2 = em.find(ChildClassA.class, 2);
  entityWithID2.mode = "b";
  em.getTransaction().commit();

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

If we try to open the database with the ObjectDB-Explorer we get the described error message.

 

If we try to ecexute a Query (in the second main method):

TypedQuery<RenamedSuperClass> q = em.createQuery("SELECT c FROM " + RenamedSuperClass.class.getName() + " c",
    RenamedSuperClass.class);
 List<RenamedSuperClass> result = q.getResultList();
 System.out.println("size: " + result.size());

We get an exception:

[2016-11-14 12:48:56 #1 *]
java.lang.NullPointerException
at com.objectdb.o.ENH.g(ENH.java:401)
at com.objectdb.o.OBC.aM(OBC.java:951)
at com.objectdb.o.OBC.UZ(OBC.java:798)
at com.objectdb.o.SRB.l(SRB.java:160)
at com.objectdb.o.QRR.m(QRR.java:549)
at com.objectdb.o.QRR.f(QRR.java:212)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:719)
at schemaupdate.delete.UpdateDB.main(UpdateDB.java:32)

Exception in thread "main" [ObjectDB 2.6.9_07] Unexpected exception (Error 990)
  Generated by Java HotSpot(TM) 64-Bit Server VM 1.8.0_51 (on Windows 7 6.1).
Please report this error on http://www.objectdb.com/database/issue/new
com.objectdb.o.InternalException: java.lang.NullPointerException: null
java.lang.NullPointerException
at com.objectdb.o.ENH.g(ENH.java:401)
at com.objectdb.o.OBC.aM(OBC.java:951)
at com.objectdb.o.OBC.UZ(OBC.java:798)
at com.objectdb.o.SRB.l(SRB.java:160)
at com.objectdb.o.QRR.m(QRR.java:549)
at com.objectdb.o.QRR.f(QRR.java:212)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:719)
at schemaupdate.delete.UpdateDB.main(UpdateDB.java:32)
#2

Thank you for your report. The test demonstrates a bug in schema evolution that includes renaming a super class and removing one of its subclasses at the same time.

After investigating this issue it seems that fixing the problem is not trival, so unfortunately we cannot provide an immediate fix.

A possible workaround is to avoid removing a class and renaming its super in the same schema change. If these changes are done separately, i.e. the database is opened between the first and the second then the schema change is expected to be processed correctly.

ObjectDB Support
#3

Ok. First we can live with the workaround that we don't removing the class in the same schema change.

Reply