D
D
Dmitry Lamzin2016-02-06 13:01:47
Java
Dmitry Lamzin, 2016-02-06 13:01:47

How to add an entity to a collection with a One-To-Many relationship without fetching the entire collection from the db?

Good afternoon. Started to deal with JPA-Hibernate. For one of my questions, I could not find an answer in the open spaces of the network. Actually, there are two questions. And so, in order.
There are two entities:
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;

Everything went smoothly until I started writing CrUD operations for the SubCategory entity, and in particular the creation of a new category:
@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;
    }

There are questions here. The entity is created, placed in the database, and it is possible to extract it by another method.
BUT!!!
Let's take a look at the sql output when calling the method.
When adding the very first subcategory, we get:
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
        (?, ?)

That is, hibernate retrieves all entities from the collection before adding a new one.
Now, if we decide to put another entity in the collection, the output will be as follows:
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
        (?, ?)

That is, the hibernate clears the JoinTable "Category_SubCategory" from all data related to the selected category, and rewrites the old entities one by one and adds a new one.
And the more entities I add, the more sql queries are added.
Questions:
1) Is it possible to add SubCategory entities to the database, but at the same time not get all the entities that are in the Category collection (because there can be thousands or more hypothetically)?
2) If not, is it possible, at least, to simply add entities to existing tables (so that hibernate does not clear the Category_SubCategory table and fill it in with a new one, but simply add a new line)?

If these options are not available, how can I optimize these operations? Is it possible to refactor entity classes?
This is my first question on the internet. So, if the information is not enough, then be sure to apnu it, just tell me.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Lamzin, 2016-02-09
@DmitriyLamzin

After some amount of meditation:
The answer to my first question is no. The collection will always get as soon as you try to access it. The output is well described here .
Second question. If nevertheless to do through association One to Many. That needs to be done not through JoinTable, which is the default, but through @JoinColumn. Then the sql for any iteration of adding an object will look like this:

Hibernate:
insert
into
SubCategory
(subCategoryName, subCategoryId)
values
(?, ?)
Hibernate:
update
SubCategory
set
subCategories_categoryId=?
where
subCategoryId=?

G
goshan_p, 2016-02-08
@goshan_p

I can’t say for sure, since the beginner himself did not ask this question. But there is a suggestion, try it? The SubCategory must have a field referring to the parent - Category categoryId with the annotation "@ManyToOne(orphanRemoval=true)". When creating an entity, you specify the parent and do the persistence of the entity without calling the parent in any way. Check it out yourself, it became interesting) True, there is no way to try it out yet

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question