Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jpa criteria for many to many relationship

Tags:

I have 2 POJO classes in Java, Answer and Collaborator, in a many-to-many relationship.

class Answer {     @ManyToMany(cascade = CascadeType.ALL)     @JoinTable(name = "ANSWERS_COLLABORATORS", joinColumns = { @JoinColumn(name = "aid") }, inverseJoinColumns = { @JoinColumn(name = "cid") })     private Set<Collaborator> collaborators = new HashSet<Collaborator>(0); }  

Class Answer has a set of Collaborator, but a Collaborator doesn't keep a set of Answer. What I need to do from Hibernate CriteriaQuery is to find the collaborators for an answer given by id.

I have already done this with Hibernate Criteria (org.hibernate.Criteria) using result transformer, but I'm stuck when it comes to using CriteriaQuery, because I don't have a list of answers to give to the join.

like image 250
user998692 Avatar asked Nov 15 '11 11:11

user998692


People also ask

What is JPA Criteria API?

The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax.

How do you create a JPA criteria?

Let's see it step by step: Create an instance of Session from the SessionFactory object. Create an instance of CriteriaBuilder by calling the getCriteriaBuilder() method. Create an instance of CriteriaQuery by calling the CriteriaBuilder createQuery() method.

What is criteria query multiselect?

CriteriaQuery. multiselect. This method takes one or more Selection items as parameters. The parameters specify the result returned by the Criteria Query. The multiselect method can be used to select a single entity, single or multiple values of the same entity or of different entities.


2 Answers

It's done, finally...

Here's the code:

public List<Collaborator> getCollaborators(Long answerId) {   CriteriaBuilder cb = entityManager.getCriteriaBuilder();   CriteriaQuery<Collaborator> criteriaQuery = cb.createQuery(Collaborator.class);      Root<Answer> answerRoot = criteriaQuery.from(Answer.class);   SetJoin<Answer, Collaborator> answers = answerRoot.join(Answer_.collaborators);   criteriaQuery.where(cb.equal(answerRoot.get(Answer_.id), answerId));      return entityManager     .createQuery(criteriaQuery.select(answers))     .getResultList(); } 
like image 63
user998692 Avatar answered Sep 16 '22 15:09

user998692


Using HQL:

You can use this:

Criteria criteria = session.createCriteria(Answer.class); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); criteria.createAlias("collaborators", "collaborators"); criteria.add(Restrictions.eq("collaborators.id",desiredCollaboratorId); 

to get all the Answers associated to a certain Collaborator.

And this:

Criteria criteria = session.createCriteria(Answer.class); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); criteria.setFetchMode("collaborators", FetchMode.JOIN) criteria.add(Restrictions.idEq(desiredAnswerId)); dsrTrackingCriteria.setProjection(Projections.property("collaborators")); 

To get all Collaborators associated to a certain Answer.

Using JPA2 Criteria API you can do something like:

CriteriaBuilder cb = em.getCriteriaBuilder(); //creted from EntityManager instance  CriteriaQuery<Long> cq = cb.createQuery(Collaborator.class); Root<Answer> rootAnswer = cq.from(Answer.class); Join<Collaborator,Answer> joinAnswerCollaborator = rootAnswer.join("collaborators"); //(or rootAnswer.join(Answer_.collaborators); if you've created the metamodel with JPA2 
like image 31
Shivan Dragon Avatar answered Sep 20 '22 15:09

Shivan Dragon