ObjectDB ObjectDB

Problems down-casting in WHERE clause

#1

I have a family of related types, like this:


@Entity
class Base {
    String val1;
    String val2;
};


@Entity
class Derived1 extends Base {
    String val3;
};


@Entity
class Derived2 extends Base {
    String val4;
};

 I'm trying to implement a query which will return all Base objects which have a given string within any of their String-typed fields.  The query I'm using looks somewhat like this:

SELECT b FROM Base b WHERE b.val1 LIKE :search OR b.val2 LIKE :search
        OR TYPE(b) = Derived1 AND ((Derived1)b).val3 LIKE :search
        OR TYPE(b) = Derived2 AND ((Derived2)b).val4 LIKE :search

When I run my query in the ObjectDB explorer, I get

Query Execution Error
=====================
null

Within my program, I get the following stack trace:

com.objectdb.o.InternalException: java.lang.NullPointerException: null
java.lang.NullPointerException
at com.objectdb.o.MMN.<init>(MMN.java:79)
at com.objectdb.o.QNF.C(QNF.java:1016)
at com.objectdb.o.QNF.z(QNF.java:789)
at com.objectdb.o.QNF.k(QNF.java:258)
at com.objectdb.o.QNF.z(QNF.java:757)
at com.objectdb.o.QNF.k(QNF.java:258)
at com.objectdb.o.QNF.t(QNF.java:611)
at com.objectdb.o.QNF.t(QNF.java:605)
at com.objectdb.o.QNF.k(QNF.java:218)
at com.objectdb.o.QNF.t(QNF.java:611)
at com.objectdb.o.QNF.t(QNF.java:605)
at com.objectdb.o.QNF.t(QNF.java:603)
at com.objectdb.o.QNF.t(QNF.java:603)
at com.objectdb.o.QNF.t(QNF.java:603)
at com.objectdb.o.QNF.k(QNF.java:224)
at com.objectdb.o.QNF.t(QNF.java:611)
at com.objectdb.o.QNF.t(QNF.java:605)
at com.objectdb.o.QNF.k(QNF.java:218)
at com.objectdb.o.QNF.j(QNF.java:135)
at com.objectdb.o.QRC.B(QRC.java:340)
at com.objectdb.o.QRC.x(QRC.java:231)
at com.objectdb.o.QRC.w(QRC.java:185)
at com.objectdb.o.QRM.U6(QRM.java:252)
at com.objectdb.o.MST.U6(MST.java:933)
at com.objectdb.o.WRA.U6(WRA.java:293)
at com.objectdb.o.WSM.U6(WSM.java:113)
at com.objectdb.o.STC.r(STC.java:450)
at com.objectdb.o.SHN.aj(SHN.java:489)
at com.objectdb.o.SHN.K(SHN.java:156)
at com.objectdb.o.HND.run(HND.java:132)
at java.lang.Thread.run(Thread.java:662)

Is this expected behavior, due to AND not being sequenced, and an attempt being made to apply the down-cast to an instance of another type?  But if that were the case, shouldn't I be getting a ClassCastException?

Is there a different way to do this, or have I simply run into a bug?

(I'm using ObjectDB 2.5.0_06)

edit
delete
#2

The following program tries to reproduce the reported problem, but not exception is thrown:

import javax.persistence.*;


@Entity
public class T1171 {

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

        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(new Derived1());
        em.persist(new Derived2());
        em.getTransaction().commit();
        em.close();
       
        em = emf.createEntityManager();
        Query query = em.createQuery(
            "SELECT b FROM Base b WHERE b.val1 LIKE :search OR b.val2 LIKE :search " +
            "OR TYPE(b) = Derived1 AND ((Derived1)b).val3 LIKE :search " +
            "OR TYPE(b) = Derived2 AND ((Derived2)b).val4 LIKE :search");
        query.setParameter("search", "");
        query.getResultList();
        em.close();

        emf.close();
    }

    @Entity
    static class Base {
        String val1;
        String val2;
    }
    
    @Entity
    static class Derived1 extends Base {
        String val3;
    }
    
    @Entity
    static class Derived2 extends Base {
        String val4;
    }
}

It seems to be a bug, but we will need your help in reproducing it. Please change the attached program so generate the exception or provide a database file with which the exception is thrown.

 

ObjectDB Support
edit
delete
#3

Thank you for looking into this.  I also could not get the simplified example to throw the exception, even after adding in a few details.  I have opened a direct support ticket to address this, which has the database in question attached (I am not attaching the database here because it contains sensitive data).

edit
delete
#4

The query in the original post doesn't have the problem that causes the exception. The query in your support ticket has the problem, but it is very complex and the same exception is also thrown for the following simpler query:

SELECT e FROM Event e
WHERE TYPE(e) = Practice AND ((Practice)e).messageList.message.matches(:search)

((Practice)e).messageList.message is an invalid expression in JPQL because messageList is a List and navigation from a list must be done by an additional variable.

ObjectDB supports navigation from lists as an extension, so the following query is valid:

SELECT e FROM Practice e
WHERE e.messageList.message.matches(:search)

but this is only supported for expressions that can be used in an ordinary JOIN definition (such as e.messageList), and ((Practice)e).messageList is not a valid FROM/JOIN range expression.

Apparently there is no support for your query in JPQL or ObjectDB and you should consider workarounds such splitting this query to more than one query.

Next build of ObjectDB will include a more friendly error message.

ObjectDB Support
edit
delete

Reply

To post on this website please sign in.