Criteria queries allow for multiple root level objects. Caution should be used when doing this, as it can result in Cartesian products of the two table. The where clause should ensure the two objects are joined in some way.
// Select the employees and the mailing addresses that have the same address.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root employee = criteriaQuery.from(Employee.class);
Root address = criteriaQuery.from(MailingAddress.class);
criteriaQuery.multiselect(employee, address);
criteriaQuery.where(criteriaBuilder.equal(employee.get("address"), address.get("address"));
Query query = entityManager.createQuery(criteriaQuery);
List<Object[]> result = query.getResultList();
B. Fonseca, P. Golgher, B. Pôssas, B. Ribeiro-Neto, and N. Ziviani. CIKM '05: Proceedings of the 14th ACM international conference on Information and knowledge management, page 696--703. New York, NY, USA, ACM Press, (2005)
J. Cugini. Information Doors -- Where Information Search and Hypertext Link workshop (held in conjunction with the ACM Hypertext and Digital Libraries conferences)., San Antonio, Texas, (2000)
J. Cugini, S. Laskowski, and M. Sebrechts. IST/SPIE's 12th Annual International Symposium: Electronic Imaging 2000: Visual Data Exploration and Analysis (SPIE 2000), San Jose, CA, (2000)
G. Stumme. Conceptual Structures at Work: 12th International Conference on Conceptual Structures (ICCS 2004), volume 3127 of LNCS, page 109-125. Heidelberg, Springer, (2004)