I've a problem with searching on lists. I'm uncertain as to what the best form is, so I've created a maven project with all the classes and a unit test showing my issue. Pretty much I want to search using cb.isMember passing an object. This however does NOT work. I'm uncertain how the database is doing its matching, but it looks to me like it matches using objectids, which means you can only match isMember if you have a database object. This does not help as I'm never going to have the real object at search time.
Trying to use join is problematic as for every extra attribute I add to the search, I need to add 2 more joins. Obviously this is not satisfactory.
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<CDI> q = cb.createQuery(CDI.class); Root<CDI> cdi = q.from(CDI.class); Join<CDI, Attribute> attributeJoin = cdi.join("attributeList"); Join<Attribute, AttributeValue> attributeValuesJoin = attributeJoin.join("attributeValues"); Join<CDI, Attribute> attributeJoin2 = cdi.join("attributeList"); Join<Attribute, AttributeValue> attributeValuesJoin2 = attributeJoin2.join("attributeValues"); Predicate pred = cb.and( cb.and( cb.equal(attributeValuesJoin.get("value"), "Alex"), cb.equal(attributeJoin.get("name"), "firstname") ), cb.and( cb.equal(attributeValuesJoin2.get("value"), "Baldwin"), cb.equal(attributeJoin2.get("name"), "lastname") ) ); q.select(cdi).where(pred); TypedQuery<CDI> typedQuery = em.createQuery(q); List<CDI> results = typedQuery.getResultList();
If I try to use isMember I have to use:
Attribute attributeLastName = em.getReference(Attribute.class, williamLastNameAttribute.getId());
which is fine in a test where I have the attribute ID, but in the real example I'll never know the id, only what the attribute contains (ie Williams last name).
I'm at my wits end over how to solve this. I don't see any way of refactoring my objects to make this search easy without compromising what I'm trying to achieve. Hopefully some will have an answer.