EntityManager getMetamodel() causes crash

#1

I am trying to track down some obscure errors with multi-threading.  This involved looking at the EntityManager Metamodel but this caused an ObjectDB exception.  So I reverted to your example code in the tutorial (with class Point) and it works as expected:

    :
    (995, 995)
    (996, 996)
    (997, 997)
    (998, 998)
    (999, 999)

If I then add one line of code to your example code:

    :
    // Store 1000 Point objects in the database:
    em.getTransaction().begin();
    for (int i = 0; i < 1000; i++)
    {
        Point p = new Point(i, i);
        em.persist(p);
    }
    em.getTransaction().commit();
        
    // ADD THIS ONE LINE...
    em.getMetamodel().getEntities().forEach(
        (e)->System.out.println("   EntityType: " +e.getName()));
    :

ObjectDB returns with:

Exception in thread "main" com.objectdb.o.UserException: Too many persistable types (>10) - exceeds evaluation limit
at com.objectdb.o.MSG.a(MSG.java:64)
at com.objectdb.o.MST.Zj(MST.java:1145)
at com.objectdb.o.WRA.Zj(WRA.java:215)
at com.objectdb.o.STC.g(STC.java:341)
at com.objectdb.o.SHN.H(SHN.java:389)
at com.objectdb.o.SHN.w(SHN.java:134)
at com.objectdb.o.HND.run(HND.java:134)
at java.lang.Thread.run(Thread.java:748)

Explorer still shows just the one type.  The log file shows the same stack trace and nothing else of note.

#2

I should add that this is on the restricted version!

Also, I can see entities one-by-one, Eg:

    Metamodel m = em.getMetamodel();
    EntityType<Point> Point_ = m.entity(Point.class);
    Point_.getAttributes().forEach(
        (a)->System.out.println("  Attr: " +a.getName()));

will return all the attributes of Point.  But I was hoping to get an idea of what the EM thought it had as a list of (persistent) entities in my multi-thread model (it's not working as expected).  NB: this last may be the subject of another post.

#3

Please provide a minimal runnable program that demonstrates the issue (see posting instructions).

Does it happen also with a new empty database?

ObjectDB Support
#4

Working code.  Note I am using a persistence.xml (shown below), which appears to cause the problem.  I am using the ObjectDB server.  I drop the db each time, so this is on an empty db.


package test;
import javax.persistence.*;

/**
 * Test Case
 */
public class MyTestCase
{
    public static void main(String[] args) 
    {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory("Test_PU");  // "objectdb://localhost/test.tmp;user=admin;password=admin;drop"
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        MyEntity e1 = new MyEntity("test1");
        em.persist(e1);
        em.getTransaction().commit();

        em.getMetamodel().getEntities().forEach((e) ->
                System.out.println("   EntityType: " +e.getName()));

        em.close();
        emf.close();
    }
}
package test;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * MyEntity
 */
@Entity
public class MyEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    
    @Id @GeneratedValue
    private long id;
    private String name;

    MyEntity(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

The persistence XML:

:
  <persistence-unit name="Test_PU" transaction-type="RESOURCE_LOCAL">
    <provider>com.objectdb.jpa.Provider</provider>
    <class>test.MyEntity</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="objectdb://localhost/test.tmp;drop"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="admin"/>
    </properties>
  </persistence-unit>

Nota Bene:  Getting the entity list works if I do not use a persistence XML.  The code works as expected with the persistence XML provided I do not get the entity list - but as noted in the post above, I can get entities individually.

#5

Maybe you have more than 10 entity classes defined in the persistence.xml file?

Even if you do not use them  em.getMetamodel().getEntities() registers them with ObjectDB.

Check the class list of the database in the Explorer.

ObjectDB Support
#6

Yes, of course that was my first thought.  Here, however is the persistence XML:

  <persistence-unit name="Test_PU" transaction-type="RESOURCE_LOCAL">
    <provider>com.objectdb.jpa.Provider</provider>
    <class>test.MyEntity</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="objectdb://localhost/test.tmp;drop"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="admin"/>
    </properties>
  </persistence-unit>

It's just the one class.  I have also attached the explorer image, ODBEntity.png which shows just the one class.

#7

Do you have other persistence units in the same persistence.xml file with additional entity classes?

ObjectDB Support
#8

No, but this shouldn't make a difference, should it?  This is the whole persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="Test_PU" transaction-type="RESOURCE_LOCAL">
    <provider>com.objectdb.jpa.Provider</provider>
    <class>test.MyEntity</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="objectdb://localhost/test.tmp;drop"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="admin"/>
    </properties>
  </persistence-unit>
</persistence>

 

 

#9

Try excluding unlisted classes:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="Test_PU" transaction-type="RESOURCE_LOCAL">
    <provider>com.objectdb.jpa.Provider</provider>
    <class>test.MyEntity</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="javax.persistence.jdbc.url" value="objectdb://localhost/test.tmp;drop"/>
      <property name="javax.persistence.jdbc.user" value="admin"/>
      <property name="javax.persistence.jdbc.password" value="admin"/>
    </properties>
  </persistence-unit>
</persistence>

Otherwise, ObjectDB may search and register all the entity classes in the classpath.

ObjectDB Support

Reply