JPA Criteria API - How to add JOIN clause (as general sentence as possible) JPA Criteria API - How to add JOIN clause (as general sentence as possible) java java

JPA Criteria API - How to add JOIN clause (as general sentence as possible)


Maybe the following extract from the Chapter 23 - Using the Criteria API to Create Queries of the Java EE 6 tutorial will throw some light (actually, I suggest reading the whole Chapter 23):

Querying Relationships Using Joins

For queries that navigate to related entity classes, the query must define a join to the related entity by calling one of the From.join methods on the query root object, or another join object. The join methods are similar to the JOIN keyword in JPQL.

The target of the join uses the Metamodel class of type EntityType<T> to specify the persistent field or property of the joined entity.

The join methods return an object of type Join<X, Y>, where X is the source entity and Y is the target of the join.

Example 23-10 Joining a Query

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);Metamodel m = em.getMetamodel();EntityType<Pet> Pet_ = m.entity(Pet.class);Root<Pet> pet = cq.from(Pet.class);Join<Pet, Owner> owner = pet.join(Pet_.owners);

Joins can be chained together to navigate to related entities of the target entity without having to create a Join<X, Y> instance for each join.

Example 23-11 Chaining Joins Together in a Query

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);Metamodel m = em.getMetamodel();EntityType<Pet> Pet_ = m.entity(Pet.class);EntityType<Owner> Owner_ = m.entity(Owner.class);Root<Pet> pet = cq.from(Pet.class);Join<Owner, Address> address = cq.join(Pet_.owners).join(Owner_.addresses);

That being said, I have some additional remarks:

First, the following line in your code:

Root entity_ = cq.from(this.baseClass);

Makes me think that you somehow missed the Static Metamodel Classes part. Metamodel classes such as Pet_ in the quoted example are used to describe the meta information of a persistent class. They are typically generated using an annotation processor (canonical metamodel classes) or can be written by the developer (non-canonical metamodel). But your syntax looks weird, I think you are trying to mimic something that you missed.

Second, I really think you should forget this assay_id foreign key, you're on the wrong path here. You really need to start to think object and association, not tables and columns.

Third, I'm not really sure to understand what you mean exactly by adding a JOIN clause as generical as possible and what your object model looks like, since you didn't provide it (see previous point). It's thus just impossible to answer your question more precisely.

To sum up, I think you need to read a bit more about JPA 2.0 Criteria and Metamodel API and I warmly recommend the resources below as a starting point.

See also

Related question


Actually you don't have to deal with the static metamodel if you had your annotations right.

With the following entities :

@Entitypublic class Pet {  @Id  protected Long id;  protected String name;  protected String color;  @ManyToOne  protected Set<Owner> owners;}@Entitypublic class Owner {  @Id  protected Long id;  protected String name;}

You can use this :

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);Metamodel m = em.getMetamodel();EntityType<Pet> petMetaModel = m.entity(Pet.class);Root<Pet> pet = cq.from(Pet.class);Join<Pet, Owner> owner = pet.join(petMetaModel.getSet("owners", Owner.class));


Warning! There's a numbers of errors on the Sun JPA 2 example and the resulting pasted content in Pascal's answer. Please consult this post.

This post and the Sun Java EE 6 JPA 2 example really held back my comprehension of JPA 2. After plowing through the Hibernate and OpenJPA manuals and thinking that I had a good understanding of JPA 2, I still got confused afterwards when returning to this post.