【发布时间】:2018-08-17 22:28:28
【问题描述】:
我有两个具有单向one to many 关系的实体。
@Entity
public class Basket {
@Id
@GeneratedValue
private Long id;
private int capacity;
}
@Entity
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
private Basket basket;
}
我保存了几个对象:
Basket basket1 = new Basket(100);
Basket basket2 = new Basket(200);
Basket basket3 = new Basket(300);
basketRepository.save(asList(basket1, basket2, basket3));
Item item1 = new Item("item1", basket1);
Item item11 = new Item("item11", basket1);
Item item2 = new Item("item2", basket2);
Item item22 = new Item("item22", basket2);
Item item3 = new Item("item3", basket3);
Item item33 = new Item("item33", basket3);
itemRepository.save(asList(item1, item11, item2, item22, item3, item33));
// Loading one item. Basket fetched eagerly.
itemRepository.findOne(1L);
// Loading many items. Baskets are not loaded (n+1 select problem).
itemRepository.findAll();
@ManyToOne 注解默认使用eager fetch。
当我使用findOne() 加载一个Item 时,Hibernate 使用left outer join 生成查询,并且在同一个查询中获取Basket。
但是,当我使用findAll() 时,Hibernate 首先获取所有Items,然后执行N selects(每个Basket 一个),因此它会导致(n+1) select problem。为什么 Hiberante 不急切地使用 findAll() 方法获取 Basket 对象以及如何解决这个问题?
【问题讨论】:
标签: java hibernate jpa spring-data eager-loading