I'd like to convert it to use the javax.persistence.criteria.CriteriaBuilder, but am unsure what do, any help is much appreciated!
SELECT * FROM User u INNER JOIN Teacher t ON t.emp_id = u.emp_id WHERE u.college_id=:college_id AND u.Book.sub_code=:sub_code AND t.lang=:lang
The retrieval of the entity manager depends on your framework and your use case. The solution assumes that you have collegeId
, subCode
and lang
as given values in your method.
You create a query for the User
which you have in your SELECT
and create a Root
for this class.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
Then, you join the different classes. As I assume that Book
is also a needed class, I would join this as well. You do not have to mention on which ID the joins should happen because you already mentioned which value is the ID with the annotation @Id
.
Join<User, Teacher> teacherJoin = root.join(User_.TEACHER);
Join<User, Book> bookJoin = root.join(User_.BOOK);
The different WHERE
conditions can be added to the criteria query. To link several WHERE
conditions, I add the conditions to a list (to eventually combine them).
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get(User_.COLLEGE_ID), collegeId));
predicates.add(cb.equal(bookJoin.get(Book_.SUB_CODE), subCode));
predicates.add(cb.equal(teacherJoin.get(Teacher_.LANG), lang));
Eventually, you have to execute the constructed query.
cq
.select(root)
.where(cb.and(predicates.toArray()));
return entityManager.createQuery(cq).getResultList();
The above answer uses the JPA Metamodel Generator to prevent you from typing your actual reference names as strings. For example, the call User_.TEACHER
gives you the actual string which refers to the Teacher
object within User
.
The following example shows the above code snippets merged together in a function.
public List<User> findAllByCollegeIdAndBookSubCodeAndTeacherLang(
String collegeId,
int subCode,
Lang lang) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
Join<User, Teacher> teacherJoin = root.join(User_.TEACHER);
Join<User, Book> bookJoin = root.join(User_.BOOK);
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get(User_.COLLEGE_ID), collegeId));
predicates.add(cb.equal(bookJoin.get(Book_.SUB_CODE), subCode));
predicates.add(cb.equal(teacherJoin.get(Teacher_.LANG), lang));
cq
.select(root)
.where(cb.and(predicates.toArray()));
return entityManager.createQuery(cq).getResultList();
}