Issue #605: Issue with TYPE expression in Criteria API

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

Find attached project using latest 2.3.4_03 odb still causes:

 

Query: SELECT $1 FROM com.test.virtual.model.MyCustomer $1 WHERE TYPE($1)=class com.test.model.Customer
Exception in thread "main" [ObjectDB 2.3.4_03] javax.persistence.PersistenceException
Attempt to store an instance of a non persistable type java.lang.Class (error 303)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:675)
at com.test.TestRun.test01(TestRun.java:68)
at com.test.TestRun.main(TestRun.java:28)
Caused by: com.objectdb.o.UserException: Attempt to store an instance of a non persistable type java.lang.Class
at com.objectdb.o.MSG.d(MSG.java:61)
at com.objectdb.o.TYW.writeElement(TYW.java:223)
at com.objectdb.o.QRR.l(QRR.java:424)
at com.objectdb.o.QRR.g(QRR.java:230)
at com.objectdb.o.QRR.b(QRR.java:151)
at com.objectdb.jpa.JpaQuery.getResultList(JpaQuery.java:666)
... 2 more
#2

Thank you for this bug report.

In the future, please submit tests using a single file format (when applicable) as explained in the posting instructions. For example, your test can be simplified (after removing unnecessary code) to:

import java.util.*;

import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

public class T605 {

    public static void main(String[] args) {
        EntityManagerFactory emf =
            Persistence.createEntityManagerFactory(
                "objectdb://localhost:6136/test/test.tmp;drop;admin");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(new Contact("Contact One"));
        em.persist(new Contact("Contact Two"));
        em.persist(new Customer("Customer One"));
        em.persist(new Customer("Customer Two"));
        em.getTransaction().commit();
        em.close();

        em = emf.createEntityManager();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Object> cq = cb.createQuery();
        Root<Customer> e = cq.from(Customer.class);
        cq.select(e);
        cq.where(cb.equal(e.type(), cb.literal(e.getJavaType())));
        System.out.println("Query: " + cq);
        List<Object> resultList = em.createQuery(cq).getResultList();
        System.out.println("Size: " + resultList.size());
        em.close();
        emf.close();
    }

    @Entity
    public static class Contact {
        private String name = null;
        public Contact(String name) {
            this.name = name;
        }

        public Contact() {
        }
    }
  
    @Entity
    public static class Customer extends Contact {
        public Customer(String name) {
            super(name);
        }
        public Customer() {
        }
    }
}

Actually this is very similar to the test on this forum thread except that your test uses client server mode. Both work well (also in client server mode) when serialization is enabled in the configuration (under <entities>):

    <persist serialization="true" />

This is required because currently passing a type argument (a Class instance) in client-server mode requires serialization. Following your report, this will be fixed in next builds.

Thanks again for this bug report.

ObjectDB Support
#3

Starting build 2.3.4_04 the test should also pass with serialization disabled.

ObjectDB Support

Reply