Question

Currently, I have a UserDao class which creates a query using CriteriaQuery, for example to retrieve an instance of User from the database using its ID (let's call that method findById). So far, it's pretty straightforward and that works fine.

However, I also have a GenericDao, which is extended by UserDao. Before userDao.findById returns its results, it passes the criteriaQuery to the GenericDao so I can add some restrictions to the criteriaQuery.

Example:

public class GenericDao
{
    private EntityManager entityManager;

    protected Object executeCriteriaQuery(CriteriaQuery criteriaQuery)
    {
        return entityManager.createQuery(prepareQuery(criteriaQuery)).getSingleResult();
    }

    private CriteriaQuery prepareQuery(CriteriaQuery criteriaQuery)
    {
        // add restrictions to criteriaQuery
        Predicate predicate = ... // some predicate which will be appended to the already formed criteriaQuery

        criteriaQuery.where(criteriaBuilder.and(criteriaQuery.getRestriction(), predicate));

        return criteriaQuery;
    }
}

public class UserDao extends GenericDao
{
    public User findById(String id)
    {
        CriteriaQuery query = criteriaBuilder.createQuery(entityClass);
        Root<P> entity = query.from(entityClass);
        query.select(entity);
        query.where(criteriaBuilder.equal(entity.get("id"), id.toUpperCase()));

        return executeCriteriaQuery(query);
    }
}

The thing is: the query that is built in the DAOs that extend my GenericDao may contain a JOIN. I want to add a predicate to a JOIN that is added to the criteriaQuery.
From what I can see, I can retrieve the JOINs in the query by using From.getJoins(). However, according to the Javadoc for that method:

Return the joins that have been made from this bound type. Returns empty set if no joins have been made from this bound type. Modifications to the set do not affect the query.

Returns: joins made from this type

How can I add a predicate to JOIN clauses in my criteriaQuery?

Was it helpful?

Solution

After some time, I decided I'm going to implement a different approach to this particular problem. Since I couldn't find any options on how to do this, I attempted to solve it on a JPA implementation level. Since I use Hibernate, I used Hibernate filters. For Eclipselink users: you can use Eclipselink's Multi tenancy feature.

Unfortunately I haven't been able to find a solution on a higher level, so I still have to write a new implementation for this if I were to switch implementations. On the other hand, I probably won't switch to new implementations on a regular basis so that probably won't be an issue.

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