Efficiently extract multiple packages

I am developing a multilingual application. For this reason, many objects have in their names and descriptions of field fields something that I call LocalizedStrings instead of simple strings. Each localized string is basically a pair of locales and a string localized in that locale.

Take an example of an object, say, a book-object.

public class Book{

 @OneToMany
 private List<LocalizedString> names;

 @OneToMany
 private List<LocalizedString> description;

 //and so on...
}

When the user requests a list of books, he performs a query to get all the books, selects the name and description of each book in the locale that the user has chosen to run the application, and displays it back to the user.

, . hibernate , , "n + 1 select". 50 , 6000 sql- .

, , " ".

, , , , . Subselects , , , .

, .

, , , , , .

+3
2

, ,

, ,

@Entity
public class Book{

    private List<LocalizedString> nameList = new ArrayList<LocalizedString>();

    @OneToMany(cascade=javax.persistence.CascadeType.ALL)
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
    public List<LocalizedString> getNameList() {
        return this.nameList;
    }

    private List<LocalizedString> descriptionList = new ArrayList<LocalizedString>();

    @OneToMany(cascade=javax.persistence.CascadeType.ALL)
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
    private List<LocalizedString> getDescriptionList() {
        return this.descriptionList;
    }



}

:

public class BookRepository implements Repository {

    public List<Book> getAll(BookFetchingStrategy fetchingStrategy) {
        switch(fetchingStrategy) {
            case BOOK_WITH_NAMES_AND_DESCRIPTIONS:
                List<Book> bookList = session.createQuery("from Book").list();

                // Notice empty statement in order to start each subselect
                for (Book book : bookList) {
                    for (Name address: book.getNameList());
                    for (Description description: book.getDescriptionList());
                }

            return bookList;
        }
    }

    public static enum BookFetchingStrategy {
        BOOK_WITH_NAMES_AND_DESCRIPTIONS;
    }

}

,

SessionFactory sessionFactory = configuration.buildSessionFactory();

Session session = sessionFactory.openSession();
session.beginTransaction();

// Ten books
for (int i = 0; i < 10; i++) {
    Book book = new Book();
    book.setName(RandomStringUtils.random(13, true, false));

    // For each book, Ten names and descriptions
    for (int j = 0; j < 10; j++) {
        Name name = new Name();
        name.setSomething(RandomStringUtils.random(13, true, false));

        Description description = new Description();
        description.setSomething(RandomStringUtils.random(13, true, false));

        book.getNameList().add(name);
        book.getDescriptionList().add(description);
    }

    session.save(book);
}

session.getTransaction().commit();
session.close();

session = sessionFactory.openSession();
session.beginTransaction();

List<Book> bookList = session.createQuery("from Book").list();

for (Book book : bookList) {
    for (Name address: book.getNameList());
    for (Description description: book.getDescriptionList());
}

session.getTransaction().commit();
session.close();

:

select
    book0_.id as id0_,
    book0_.name as name0_ 
from
    BOOK book0_

Hibernate: 100 ( )

select
    namelist0_.BOOK_ID as BOOK3_1_,
    namelist0_.id as id1_,
    namelist0_.id as id1_0_,
    namelist0_.something as something1_0_ 
from
    NAME namelist0_ 
where
    namelist0_.BOOK_ID in (
        select
            book0_.id 
        from
            BOOK book0_
    )

Hibernate: 100 ( )

select
    descriptio0_.BOOK_ID as BOOK3_1_,
    descriptio0_.id as id1_,
    descriptio0_.id as id2_0_,
    descriptio0_.something as something2_0_ 
from
    DESCRIPTION descriptio0_ 
where
    descriptio0_.BOOK_ID in (
        select
            book0_.id 
        from
            BOOK book0_
    )

. "n + 1". , . .

+3

batch-size , , Hibernate

Hibernate doc

+1

Source: https://habr.com/ru/post/1741919/


All Articles