Mindaugas Jaraminas
Mindaugas Jaraminas

Reputation: 3437

JPA CriteriaBuilder Joins with extra ON clause parameters (predicate)

How to join with extra ON clause parameters? I have an SQL:

select * from Address address left outer join  AddressLine line 
              on line.id = address.lineId AND line.type = 'MA'
where address.id = 1;

I have code:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<AddressResult> query = cb.createQuery(AddressResult.class);
Root<Address> r = query.from(Address.class);
Join<Address, AddressLineMA >linesMA= r.join(Address_.linesMajor, JoinType.LEFT);

To get data from data base. This query is not working as expected I get SQL like this:

select * from Address address left outer join  AddressLine line 
              on line.id = address.lineId 
    where address.id = 1;

AND line.type = 'MA' is missing. Does some one knows how to fix this?

My AddressLineMA.class looks like this:

@Entity
@DiscriminatorValue(value = "MA")
public class AddressLineMA extends AddressLine {

}
@Entity
@Table(name = "AddressLine")
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING)
public abstract class AddressLine {
   private Long id;
   private String type;
   private String line;
}

Upvotes: 1

Views: 1920

Answers (1)

Chris
Chris

Reputation: 21145

JPA queries always return all subclasses by default. So if you want only instances of AddressLineMA, you must change your query and relationshipto be on AddressLineMA instead of the inheritance root class, AddressLine.

If there are other subclasses of AddressLineMA that you want to exclude, then you can use the TYPE operator added to JPA 2.0:

   query.where(cb.equal(linesMA.type(), package.AddressLineMA.class));

Unfortunately, adding it into the ON clause is only supported in the yet to be released JPA 2.1 spec:

   linesMA.on(cb.equal(linesMA.type(), package.AddressLineMA.class));

Upvotes: 4

Related Questions