Как добавить сущность в коллекцию со связью One-To-Many, не извлекая всю коллекцию из БД?

Добрый день. Начал разбираться с 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 и заполнял ее по новой, а просто добавлял новую строчку) ?


Если эти опции не доступны, то как мне оптимизировать данные операции? Возможно отрефакторить классы сущностей?

Это мой первый вопрос в интернете. Так что, если инфы не достаточно, то обязательно апну его, только скажите.
  • Вопрос задан
  • 1032 просмотра
Решения вопроса 1
@DmitriyLamzin Автор вопроса
После некоторого количества медитации:

На первый мой вопрос ответ - нет. Коллекция будет всегда доставаться, как только к ней попытаться обратиться. Выход хорошо описан здесь.

Второй вопрос. Если все же делать через ассоциацию One to Many. То нужно делать не через JoinTable, что по умолчанию, а через @JoinColumn. Тогда sql для любой итерации добавления объекта будет выглядеть так:
Hibernate:
insert
into
SubCategory
(subCategoryName, subCategoryId)
values
(?, ?)
Hibernate:
update
SubCategory
set
subCategories_categoryId=?
where
subCategoryId=?
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@goshan_p
Точно не скажу, так как сам начинающий и не задавался этим вопросом. Но есть предположение, опробуете? У SubCategory должно быть поле ссылающееся на родителя - Category categoryId c аннотацией "@ManyToOne(orphanRemoval=true)". При создании сущности указываете родителя и делаете persist сущности при том не вызывая родителя никак. Проверьте, самому стало интересно) Правда пока нет возможности опробывать
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы