NESTED包的JPA查询方法

r6l8ljro  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(144)

对于multibags,我已经遵循并实现了Vlad Mihalcea的伟大帖子The best way to fix the Hibernate MultipleBagFetchException

public class Car {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
    private List<CarWheel> wheels = new ArrayList<>();

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
    private List<CarDoor> doors = new ArrayList<>();
}

如果不使用MultiBagException,则获取汽车及其门窗列表的查询将是

List<Car> cars = em.createQuery("select distinct c from Car c
                 left join fetch c.windows", Car.class)
                 .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
                 .getResultList();

          cars = em.createQuery("select distinct c from Car c
                 left join fetch c.doors where c in :cars", Car.class)
                 .setParameter("cars", cars)
                 .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
                 .getResultList();
 return cars;

但我如何适应这种方法,当它是一个单一的袋子,这个袋子有一个袋子自己。如何在一个查询中获得汽车及其车轮和车轮螺母的列表?

public class CarWheel {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "wheel")
    private List<LugNuts> lugs = new ArrayList<>();
}

我的工作是循环遍历汽车数组,然后查询每辆车的车轮的凸耳。但我认为这不是最好的方法,因为在一个循环中进行多个db调用效率不高。但是,如果我没有显式地查询lug,就会得到LazyLoad异常。这是一个简单的例子。

bq3bfh9z

bq3bfh9z1#

这就是方法。但是您的CarWheel实体必须提供ManyToOneCar的关系,或者包含carId作为列。

List<Car> cars = em.createQuery("select distinct c from Car c
                 left join fetch c.windows", Car.class)
                 .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
                 .getResultList();

          cars = em.createQuery("select distinct c from Car c
                 left join fetch c.doors where c in :cars", Car.class)
                 .setParameter("cars", cars)
                 .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
                 .getResultList();
          
          List<CarWheel> carWheels = em.createQuery("select distinct cw from CarWheel cl
                 left join fetch cw.lugs where cw.car.id in :carIds", CarWheel.class)
                 .setParameter("carIds", cars.stream().map(c -> c.getId()).toList())
                 .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
                 .getResultList();
// CarWheel.lugs entities are in persistent context.
// So, car.getWheel()...getLugs() will not trigger another SELECT statement 
return cars;

相关问题