Question

Okay, I'm trying to do something quite strange. I'm trying to use CriteriaBuilder and CriteriaQuery to return all entities who contain a given object in a collection on the entity. I've been banging my head against this for hours and the relevant documentation is little and not particularly useful. Any help would be greatly appreciated.

Relevant excerpts of the classes are as follows.

@Entity
public class Entry {
    @ManyToMany(fetch=FetchType.EAGER)
    private List<Tag> tags = new ArrayList<Tag>();
}

@Entity
public class Tag {
    @Size(min=1,max=63)
    @Column(unique=true)
    @NotNull
    private String name;
}

@Repository
@Transactional
public class EntryDaoImpl extends RefineableDao implements EntryDao{
    @Autowired
    private EntityManager em;

    @Override
    public List<Entry> search(final Map<String,Object> refinement){
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Entry> query = cb.createQuery(Entry.class);
        Root<Entry> entry = query.from(Entry.class);
        query.orderBy(cb.desc(entry.get("createTime")));
        query.select(entry);
        query.where(this.refineQuery(refinement, cb, query, entry));
        return em.createQuery(query).getResultList();
    }
}

So basically, I need to be able to find Entries which contain a given Tag. I know that this could be done quite simply if it was the only refinement I was doing, but there are a lot of other refinements being done to the same CriteriaQuery, and I never have any guarantees of which refinements are going to be going through.

If you really need to know the backend, take a look at http://pastebin.com/QJnkYRRh . It's a horrible un-commented mess.

Was it helpful?

Solution

Okay. I've found my answer as to why I was having problems with CriteriaBuilder.isMember(). The issue is that the Path needs to be Path<? extends Collection>. With that, isMember() works just like I was hoping it would.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top