@OneToOne делает sql запрос на каждый объект в таблице
Всем привет, сделал необходимые entity под БД:
@Getter
@Setter
@Accessors(chain = true)
@Entity
@Table(name = "****", schema = "****")
public class ShopProductEntity implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id", nullable = false)
private Integer id;
@OneToOne
@JoinColumn(name = "sku_id", referencedColumnName = "id")
private ShopProductSkusEntity sku;
}
@Getter
@Setter
@Accessors(chain = true)
@Entity
@Table(name = "****", schema = "*****")
public class ShopProductSkusEntity implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id", nullable = false)
private Integer id;
@Basic
@Column(name = "product_id", nullable = false)
private Integer productId;
@Basic
@Column(name = "sku", nullable = false, length = 255)
private String sku;
}
И когда делаю запрос на получение всех элементов таблицы:
public synchronized List<ShopProductEntity> getAllProducts() {
return em.createQuery("SELECT a FROM ShopProductEntity a", ShopProductEntity.class)
.getResultList();
}
То вижу по логам Hibernate, что происходит первый запрпос на получение всех строк из ShopProductEntity, а потом для каждой записи - происходит отдельный запрос в ShopProductSkusEntity:
Hibernate: select shopproduc0_.id as id1_4_, shopproduc0_.sku_id as sku_id2_4_ from shop_product shopproduc0_
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
Hibernate: select shopproduc0_.id as id1_7_0_, shopproduc0_.product_id as product_2_7_0_, shopproduc0_.sku as sku3_7_0_ from shop_product_skus shopproduc0_ where shopproduc0_.id=?
и так далее . . .
А записей в ShopProductEntity порядка 180000 и Hibernate делает запросы не паралельно, а в одном потоке. И каждый запрос занимает где-то 0.2-0.3 мс, что приводит к неопределенному кол-во времени в ожидании, пока всё выгрузиться (явно более 1 часа).
Вопрос: Как оптимизировать этот момент? Может как-то можно указать Hibernate, чтобы он кэшировал сразу всю таблицу ShopProductSkusEntity и не обращался постоянно к БД? Или есть какие-то другие варианты, может это проблема N+1 и надо копать в эту сторону?