Добрый день. Начал разбираться с JPA-Hibernate. На один свой вопрос так и не смог найти ответа в просторах сети. Вообще то вопроса два. И так, по порядку.
Имеется две сущности:
1)
@Entity
public class Category implements Serializable {
@Id
String categoryId;
String name;
@OneToMany
List<SubCategory> subCategories = new ArrayList<SubCategory>();
2)
@Entity
public class SubCategory {
@Id
String subCategoryId;
String subCategoryName;
Все шло гладко, пока не начал писать CrUD операции для сущности SubCategory, а в частности создание новой категории:
@Transactional
@Repository ("subCategoryDao")
public class JpaSubCategoryDaoImpl implements SubCategoryDao {
@PersistenceContext
EntityManager em;
public SubCategory createSubCategory(SubCategory subCategory, String categoryId) {
Category category = em.getReference(Category.class, categoryId);
category.getSubCategories().add(subCategory);
em.persist(subCategory);
return subCategory;
}
Здесь появились вопросы. Сущность создается, ложится в БД и другим методом возможно ее извлечь.
НО!!!
Взглянем на вывод sql при обращении к методу.
При добавлении самой первой подкатегории получаем:
Hibernate:
select
category0_.categoryId as category1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.categoryId=?
Hibernate:
select
subcategor0_.Category_categoryId as Category1_1_0_,
subcategor0_.subCategories_subCategoryId as subCateg2_1_0_,
subcategor1_.subCategoryId as subCateg1_3_1_,
subcategor1_.subCategoryName as subCateg2_3_1_
from
Category_SubCategory subcategor0_
inner join
SubCategory subcategor1_
on subcategor0_.subCategories_subCategoryId=subcategor1_.subCategoryId
where
subcategor0_.Category_categoryId=?
Hibernate:
insert
into
SubCategory
(subCategoryName, subCategoryId)
values
(?, ?)
Hibernate:
insert
into
Category_SubCategory
(Category_categoryId, subCategories_subCategoryId)
values
(?, ?)
То есть, хибернейт ретривит все сущности из коллекции, перед добавлением новой.
Теперь, если мы решим положить в коллекцию еще одну сущность вывод будет следующим:
Hibernate:
select
category0_.categoryId as category1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.categoryId=?
Hibernate:
select
subcategor0_.Category_categoryId as Category1_1_0_,
subcategor0_.subCategories_subCategoryId as subCateg2_1_0_,
subcategor1_.subCategoryId as subCateg1_3_1_,
subcategor1_.subCategoryName as subCateg2_3_1_
from
Category_SubCategory subcategor0_
inner join
SubCategory subcategor1_
on subcategor0_.subCategories_subCategoryId=subcategor1_.subCategoryId
where
subcategor0_.Category_categoryId=?
Hibernate:
insert
into
SubCategory
(subCategoryName, subCategoryId)
values
(?, ?)
Hibernate:
delete
from
Category_SubCategory
where
Category_categoryId=?
Hibernate:
insert
into
Category_SubCategory
(Category_categoryId, subCategories_subCategoryId)
values
(?, ?)
Hibernate:
insert
into
Category_SubCategory
(Category_categoryId, subCategories_subCategoryId)
values
(?, ?)
То есть, хибернейт отчищает JoinTable "Category_SubCategory" от всех данных, относящихся к выбранной категории, и заново записывает туда старые сущности по одной и добавляет новую.
И чем больше сущностей я добавляю, тем больше sql запросов добавляется.
Вопросы:
1) Можно ли добавлять сущности SubCategory в БД, но при этом не доставать все сущности, которые находятся в коллекции Category (т.к. гепотетически их могут быть тысячи и больше)?
2) Если нет, то можно ли, хотя бы, просто добавлять сущности к уже существующим табицам (что бы хибернейт не отчищал таблицу Category_SubCategory и заполнял ее по новой, а просто добавлял новую строчку) ?
Если эти опции не доступны, то как мне оптимизировать данные операции? Возможно отрефакторить классы сущностей?
Это мой первый вопрос в интернете. Так что, если инфы не достаточно, то обязательно апну его, только скажите.