Hello ObjectDB team,
I am getting a ClassCastException with following stack trace:
Caused by: java.lang.ClassCastException: com.objectdb.jpa.criteria.JoinImpl cannot be cast to com.objectdb.o.TPE at com.objectdb.o.TPL.get(TPL.java:91) at pl.hobsoft.lohare.server.BusinessService.lambda$4(BusinessService.java:732) at pl.hobsoft.lohare.server.BusinessService$$Lambda$6/297307723.apply(Unknown Source) at com.google.common.collect.Lists$TransformingRandomAccessList$1.transform(Lists.java:651) at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:48) at java.util.AbstractCollection.toArray(AbstractCollection.java:196) at pl.hobsoft.lohare.server.BusinessService.findFinishedDemands(BusinessService.java:736) at pl.hobsoft.lohare.server.jsp.views.UserAccountView.findDemands(UserAccountView.java:78) at pl.hobsoft.lohare.server.jsp.views.UserAccountView.init(UserAccountView.java:62) ... 50 more
This time I am not saying it's a bug ;) however with just ClassCastException and without any further explanation (especially without knowledge what com.objectdb.o.TPE is and what TPE.get expects) it's difficult for me to pin the problem down. Is it possible to add type check before the cast and throw more meaningful exception in such case?
If you are interested, my code:
EntityManager em = createEm(); try { ProvidingPerson storedProvidingPerson = load(em, providingPerson); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Tuple> cq = cb.createTupleQuery(); Root<DemandAnswer> rootDemandAnswer = cq.from(DemandAnswer.class); Join<DemandAnswer, Demand> joinDemand = rootDemandAnswer.join("demand"); Join<Object, Object> joinDemandingPerson = joinDemand.join("demandingPerson"); Join<Object, Object> joinProvidingPerson = rootDemandAnswer.join("providingPerson"); joinDemand.join("execution"); joinDemand.fetch("services"); joinDemandingPerson.fetch("account"); cq.multiselect(joinDemand, rootDemandAnswer).distinct(true); cq.where( cb.equal(joinProvidingPerson, storedProvidingPerson) ); TypedQuery<Tuple> query = em.createQuery(cq); List<Tuple> tuples = query.getResultList(); List<DemandDetails> candidateDemands = Lists.transform(tuples, d -> { //Demand demand = (Demand) d.get(0); //DemandAnswer answer = (DemandAnswer) d.get(1); Demand demand = d.get(joinDemand); DemandAnswer answer = d.get(rootDemandAnswer); return new DemandDetails(demand, answer); }); DemandDetails[] demands = candidateDemands.toArray(new DemandDetails[candidateDemands.size()]); return demands; } finally { em.close(); }
Commented out calls to Tuple.get(int) work as expected, array Tuple.b contains expected values. Also note that call to Lists.transform is evaluated lazily, that's why stacktrace looks the way it does. Lazy evaluation of Guava methods is sometimes a problem when working with ObjectDB (and other libraries as well), but I do not think it's the cause of above error.
Do you have any suggestions what I am doing wrong?
PS. I am really sorry for the formatting, but I cannot get this to work;