Почему @Basic (fetch = lazy) не работает в моем случае?

Я знаю, что подобные вопросы уже задавали много раз, но я не нашел ни одного, который мог бы мне помочь.

Итак, могу ли я попросить вас помочь мне найти причину, по которой Booktitle загружается EAGERly?

У меня очень простая кодовая база, вот моя сущность:

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class Book {

    @Id
    @GeneratedValue
    private int id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;

}

А вот клиентский фрагмент кода, в данном случае представленный psvm():

public static void main(String[] args) {

    final ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    final SessionFactory sessionFactory = context.getBean(SessionFactory.class);
    Session session = sessionFactory.openSession();

    Book book = Book.builder().title("Peace and War").build();

    Transaction tx = session.beginTransaction();
    session.save(book);
    tx.commit();
    session.close();

    session = sessionFactory.openSession();
    book = session.get(Book.class, book.getId());
}

Я также добавил плагин к maven для улучшения байт-кода:

   <build>
        <plugins>
            <plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>5.3.6.Final</version>
                <executions>
                    <execution>
                        <configuration>
                            <enableLazyInitialization>true</enableLazyInitialization>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
   </build>

Но, тем не менее, title с нетерпением ждут по следующему запросу:

Hibernate: select book0_.id as id1_0_0_, book0_.title as title2_0_0_ from Book book0_ where book0_.id=?

что я вижу из-за hibernate.show_sql=true

Не могли бы вы помочь мне понять, что я делаю не так? Кажется, ответ лежит на поверхности, но я не могу его заметить.

Помогло бы это stackoverflow.com/questions/43749821/…_

Michal 03.09.2018 19:55

Если вы используете FetchType.LAZY, разве связанный объект не должен быть аннотирован с помощью @Entity? то есть вы не можете использовать его со String. Нет смысла использовать его со строкой, иначе не существует сценария, когда вы действительно извлекаете его, кроме как при извлечении основного объекта, в данном случае Book.

JamesB 03.09.2018 19:58

Ленивая выборка простых типов (например, примитивов, их оберток, строк и т. д.) Может не поддерживаться. В любом случае это обычно не имеет особого смысла.

Thomas 03.09.2018 19:59

Почему Hibernate просто не может создать прокси-сервер класса Entity для обеспечения отложенной загрузки для оболочек, строк и т. д.?

Pasha 03.09.2018 20:01

В большинстве случаев ленивая загрузка свойств не имеет особого смысла, поскольку вам потребуется больше запросов для получения свойств, и если вас интересуют только некоторые из них, вы всегда можете вместо этого использовать запрос типа select book.id from Book book ....

Thomas 03.09.2018 20:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
394
1

Ответы 1

 @Basic(fetch = FetchType.LAZY, optional = false)

В соответствии со спецификацией JPA @Basic «Ленивая загрузка» не гарантируется в зависимости от того, какую реализацию вы используете. Вы можете проверить это здесь https://en.wikibooks.org/wiki/Java_Persistence/Basic_Attributes

Support for LAZY fetching on Basic is optional in JPA, so some JPA providers may not support it.

В любом случае, один из способов обхода проблемы - создать новую отдельную сущность, скажем, например, BookTitle, затем установить взаимно-однозначное отношение и лениво загрузить ее из сущности книги:

public class BookTitle {
    @Id
    @GeneratedValue
    private Long id;

    @Lob
    @Basic(fetch = FetchType.LAZY, optional = false)
    private String title;
}


public class Book {

    @Id
    @GeneratedValue
    private int id;

    @OneToOne (fetch = FetchType.LAZY)
    private BookTitle bookTitle;

}

Другие вопросы по теме