Left outer join of unrelated entities with Criteria
Asked Answered
F

2

5

Is it somehow possible to create a criteria query that performs an outer join on another entity if that entity is not mapped?

I know that an inner join is possible when you do a cross join and add the join condition manually. It would look like this:

CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();

Root<Car> car = cq.from(Car.class);
Root<Color> color = cq.from(Ccolor.class);

cq.where(cb.equal(car.get("colorUuid"), color.get("uuid")));

However I need the behaviour of an outer join in my case.

So let's say I have these entities:

class Car {
  @Column(name="color_uuid")
  private String colorUuid;
}

class Color {
  private String uuid;
  private String name;
}

Lets say Color is optional and that's why I need an outer join. The SQL would look like

SELECT * from car LEFT OUTER JOIN color ON car.color_uuid = color.uuid;

Can I do this with Criteria?

Flaunch answered 2/3, 2022 at 10:10 Comment(1)
Check if this helps: vladmihalcea.com/…Gordon
P
2

You can’t do this with criteria api without making the entities in relation, I’ve faced the same problem as you. Also a cross join can’t help. What I can suggest is:

  1. make a view with the left outer join on the database and then map the view as an entity
  2. make a jpql query
  3. make a native query
Purulence answered 1/8, 2022 at 19:12 Comment(0)
T
-2

I suggest you change the classes in order to have a relationship that logically already exists.

class Car {
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "color_uuid", referencedColumnName = "uuid")
    private Color color;
}

class Color {
    private String uuid;
    private String name;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "color")
    private List<Car> cars;
}

Then you can build the left join using criteria:

CriteriaQuery<Car> criteriaQuery = criteriaBuilder.createQuery(Car.class);
Root<Car> root = criteriaQuery.from(Car.class);
root.join("color", JoinType.LEFT);
List<Car> cars = em.createQuery(criteriaQuery).getResultList();
Torbert answered 2/3, 2022 at 10:39 Comment(1)
I don't want to add a mapping. That's why I have explicitly asked for unrelated entities.Flaunch

© 2022 - 2024 — McMap. All rights reserved.