Собеседование по Java EE — Hibernate Framework (вопросы и ответы). Часть 1

Вопросы и ответы на собеседование по теме Hibernate Framework. Часть 1.

к списку вопросов раздела JEE

Собеседование по Java EE — Hibernate Framework (вопросы и ответы). Часть 2.

Вопросы

1. Что такое Hibernate Framework?
2. Какие важные преимущества дает использование Hibernate Framework?
3. Каковы преимущества Hibernate над JDBC?
4. Назовите некоторые важные интерфейсы Hibernate.
5. Что такое конфигурационный файл Hibernate?
6. Что такое Hibernate mapping file?
7. Назовите некоторые важные аннотации, используемые для отображения в Hibernate.
8. Что вы знаете о Hibernate SessionFactory и как его сконфигурировать?
9. Является ли Hibernate SessionFactory потокобезоспансым?
10. Как получить Hibernate Session и что это такое?
11. Является ли Hibernate Session потокобезоспаным?
12. В чем разница между openSession и getCurrentSession?
13. Какая разница между методами Hibernate Session get() и load()?
14. Что вы знаете о кэширование в Hibernate? Объясните понятие кэш первого уровня в Hibernate?
15. Как настроить кэш второго уровня в Hibernate с помощью EHCache?
16. Каковы существуют различные состояния у entity bean?
17. Как используется вызов метода Hibernate Session merge()?
18. В чем разница между Hibernate save(), saveOrUpdate() и persist()?
19. Что произойдет, если будет отсутствовать конструктор без аргументов у Entity Bean?
20. В чем разница между sorted collection и ordered collection? Какая из них лучше?
21. Какие типы коллекций в Hibernate вы знаете?
22. Как реализованы Join’ы Hibernate?
23. Почему мы не должны делать Entity class как final?
24. Что вы знаете о HQL и каковы его преимущества?
25. Что такое Query Cache в Hibernate?
26. Можем ли мы выполнить нативный запрос SQL (sql native) в Hibernate?
27. Назовите преимущества поддержки нативного sql в Hibernate.
28. Что такое Named SQL Query?
29. Каковы преимущества Named SQL Query?
30. Расскажите о преимуществах использования Hibernate Criteria API.


31. Как логировать созданные Hibernate SQL запросы в лог-файлы?
32. Что вы знаете о Hibernate прокси и как это помогает в ленивой загрузке (lazy load)?
33. Как реализованы отношения в Hibernate?
34. Как управлять транзакциями с помощью Hibernate?
35. Что такое каскадные связи (обновления) и какие каскадные типы есть в Hibernate?
36. Как добавить логирование log4j в Hibernate приложение?
37. Как использовать JNDI DataSource сервера приложений с Hibernate Framework?
38. Как интегрировать Hibernate и Spring?
39. Что вы знаете о классе HibernateTemplate?
40. Как интегрировать Hibernate с Servlet или Struts2 веб приложением?
41. Какие паттерны применяются в Hibernate?
42. Расскажите о Hibernate Validator Framework.
43. Какие преимущества дает использование плагина Hibernate Tools Eclipse?
44. Best Practices в Hibernate.

Ответы

1. Что такое Hibernate Framework?

Hibernate — библиотека для языка программирования Java, предназначенная для решения задач объектно-реляционного отображения (object-relational mapping — ORM). Она представляет собой свободное программное обеспечение с открытым исходным кодом (open source), распространяемое на условиях GNU Lesser General Public License. Данная библиотека предоставляет легкий в использовании каркас (фреймворк) для отображения объектно-ориентированной модели данных в традиционные реляционные базы данных. Hibernate совместима с JSR-220/317 и предоставляет стандартные средства JPA.

2. Какие важные преимущества дает использование Hibernate Framework?

Hibernate является одним из самых востребованных ORM фреймворков для Java. И вот почему:

  1. Hibernate устраняет множество спагетти кода (повторяющегося), который постоянно преследует разработчика при работе с JDBC. Скрывает от разработчика множество кода, необходимого для управления ресурсами и позволяет сосредоточиться на бизнес логике.
  2. Hibernate поддерживает XML так же как и JPA аннотации, что позволяет сделать реализацию кода независимой.
  3. Hibernate предоставляет собственный мощный язык запросов (HQL), который похож на SQL. Стоит отметить, что HQL полностью объектно-ориентирован и понимает такие принципы, как наследование, полиморфизм и ассоциации (связи).
  4. Hibernate — широко распространенный open source проект. Благодаря этому доступны тысячи открытых статей, примеров, а так же документации по использованию фреймворка.
  5. Hibernate легко интегрируется с другими Java EE фреймворками, например, Spring Framework поддерживает встроенную интеграцию с Hibernate.
  6. Hibernate поддерживает ленивую инициализацию используя proxy объекты и выполняет запросы к базе данных только по необходимости.
  7. Hibernate поддерживает разные уровни cache, а следовательно может повысить производительность.
  8. Важно, что Hibernate может использовать чистый SQL, а значит поддерживает возможность оптимизации запросов и работы с любым сторонним вендором БД и его фичами.

3. Каковы преимущества Hibernate над JDBC?

Hibernate имеет ряд преимуществ перед JDBC API:

  1. Hibernate удаляет множество повторяющегося кода из JDBC API, а следовательно его легче читать, писать и поддерживать.
  2. Hibernate поддерживает наследование, ассоциации и коллекции, что не доступно в JDBC API.
  3. Hibernate неявно использует управление транзакциями. Большинство запросов нельзя выполнить вне транзакции. При использовании JDBC API для управления транзакциями нужно явно использовать commit и rollback.
  4. JDBC API throws SQLException, которое относится к проверяемым исключениям, а значит необходимо постоянно писать множество блоков try-catch. В большинстве случаев это не нужно для каждого вызова JDBC и используется для управления транзакциями. Hibernate оборачивает исключения JDBC через непроверяемые JDBCException или HibernateException, а значит нет необходимости проверять их в коде каждый раз. Встроенная поддержка управления транзакциями в Hibernate убирает блоки try-catch.
  5. Hibernate Query Language (HQL) более объектно ориентированный и близкий к Java язык запросов, чем SQL в JDBC.
  6. Hibernate поддерживает кэширование, а запросы JDBC — нет, что может понизить производительность.
  7. Конфигурация Hibernate позволяет использовать JDBC вроде соединения по типу JNDI DataSource для пула соединений. Это важная фича для энтерпрайз приложений, которая полностью отсутствует в JDBC API.
  8. Hibernate поддерживает аннотации JPA, а значит код является переносимым на другие ORM фреймворки, реализующие стандарт, в то время как код JDBC сильно привязан к приложению.

4. Назовите некоторые важные интерфейсы Hibernate.

  1. SessionFactory (org.hibernate.SessionFactory) — неизменяемый потокобезопасный объект с компилированным маппингом для одной базы данных. Необходимо инициализировать SessionFactory всего один раз. Экземпляр SessionFactory используется для получения объектов Session, которые используются для операций с базами данных.
  2. Session (org.hibernate.Session) — однопоточный короткоживущий объект, который предоставляет связь между объектами приложения и базой данных. Он оборачивает JDBC java.sql.Connection и работает как фабрика для org.hibernate.Transaction. Разработчик должен открывать сессию по необходимости и закрывать ее сразу после использования. Экземпляр Session является интерфейсом между кодом в java приложении и hibernate framework и предоставляет методы для операций CRUD.
  3. Transaction (org.hibernate.Transaction) — однопоточный короткоживущий объект, используемый для атомарных операций. Это абстракция приложения от основных JDBC или JTA транзакций. org.hibernate.Session может занимать несколько org.hibernate.Transaction в определенных случаях.

5. Что такое конфигурационный файл Hibernate?

Файл конфигурации Hibernate содержит в себе данные о базе данных и необходим для инициализации SessionFactory. В .xml файле необходимо указать вендора базы данных или JNDI ресурсы, а так же информацию об используемом диалекте, что поможет hibernate выбрать режим работы с конкретной базой данных.

6. Что такое Hibernate mapping file?

Файл отображения (mapping file) используется для связи entity бинов и колонок в таблице базы данных. В случаях, когда не используются аннотации JPA, файл отображения .xml может быть полезен (например при использовании сторонних библиотек).

7. Назовите некоторые важные аннотации, используемые для отображения в Hibernate.

Hibernate поддерживает как аннотации из JPA, так и свои собственные, которые находятся в пакете org.hibernate.annotations. Наиболее важные аннотации JPA и Hibernate:

  1. javax.persistence.Entity: используется для указания класса как entity bean.
  2. javax.persistence.Table: используется для определения имени таблицы из БД, которая будет отображаться на entity bean.
  3. javax.persistence.Access: определяет тип доступа, поле или свойство. Поле — является значением по умолчанию и если нужно, чтобы hibernate использовать методы getter/setter, то их необходимо задать для нужного свойства.
  4. javax.persistence.Id: определяет primary key в entity bean.
  5. javax.persistence.EmbeddedId: используется для определения составного ключа в бине.
  6. javax.persistence.Column: определяет имя колонки из таблицы в базе данных.
  7. javax.persistence.GeneratedValue: задает стратегию создания основных ключей. Используется в сочетании с javax.persistence.GenerationType enum.
  8. javax.persistence.OneToOne: задает связь один-к-одному между двумя сущностными бинами. Соответственно есть другие аннотации OneToMany, ManyToOne и ManyToMany.
  9. org.hibernate.annotations.Cascade: определяет каскадную связь между двумя entity бинами. Используется в связке с org.hibernate.annotations.CascadeType.
  10. javax.persistence.PrimaryKeyJoinColumn: определяет внешний ключ для свойства. Используется вместе с org.hibernate.annotations.GenericGenerator и org.hibernate.annotations.Parameter.

8. Что вы знаете о Hibernate SessionFactory и как его сконфигурировать?

SessionFactory является фабрикой классов и используется для получения объектов session. SessionFactory отвечает за считывание параметров конфигурации Hibernate и подключение к базе данных. Обычно в приложении имеется только один экземпляр SessionFactory и потоки, обслуживающие клиентские запросы, получают экземпляры session с помощью объекта SessionFactory. Внутреннее состояние SessionFactory неизменно (immutable). Internal state (внутреннее состояние) включает в себя все метаданные об Object/ Relational Mapping и задается при создании SessionFactory.

SessionFactory также предоставляет методы для получения метаданных класса и статистики, вроде данных о втором уровне кэша, выполняемых запросах и т.д.

9. Является ли Hibernate SessionFactory потокобезоспансым?

Т.к. объект SessionFactory immutable (неизменяемый), то да, он потокобезопасный. Множество потоков может обращаться к одному объекту одновременно.

10. Как получить Hibernate Session и что это такое?

Объект Hibernate Session является связью между кодом java приложения и hibernate. Это основной интерфейс для выполнения операций с базой данных. Жизненный цикл объекта session связан с началом и окончанием транзакции. Этот объект предоставляет методы для CRUD (create, read, update, delete) операций для объекта персистентности. С помощью этого экземпляра можно выполнять HQL, SQL запросы и задавать критерии выборки.

11. Является ли Hibernate Session потокобезоспаным?

Объект Hibernate Session не является потокобезопасным. Каждый поток должен иметь свой собственный объект Session и закрывать его по окончанию.

12. В чем разница между openSession и getCurrentSession?

Hibernate SessionFactory getCurrentSession() возвращает сессию, связанную с контекстом. Но для того, чтобы это работало, нам нужно настроить его в конфигурационном файле hibernate. Так как этот объект session связан с контекстом hibernate, то отпадает необходимость к его закрытию. Объект session закрывается вместе с закрытием SessionFactory.

Метод Hibernate SessionFactory openSession() всегда создает новую сессию. Мы должны обязательно контролировать закрытие объекта сеанса по завершению всех операций с базой данных. Для многопоточной среды необходимо создавать новый объект session для каждого запроса.

Существует еще один метод openStatelessSession(), который возвращает session без поддержки состояния. Такой объект не реализует первый уровень кэширования и не взаимодействует с вторым уровнем. Сюда же можно отнести игнорирование коллекций и некоторых обработчиков событий. Такие объекты могут быть полезны при загрузке больших объемов данных без удержания большого кол-ва информации в кэше.

13. Какая разница между методами Hibernate Session get() и load()?

Hibernate session обладает различными методами для загрузки данных из базы данных. Наиболее часто используемые методы для этого — get() и load().

  • get() загружает данные сразу при вызове, в то время как load() использует прокси объект и загружает данные только тогда, когда это требуется на самом деле. В этом плане load() имеет преимущество в плане ленивой загрузки данных.
  • load() бросает исключение, когда данные не найдены. Поэтому его нужно использовать только при уверенности в существовании данных.
  • Нужно использовать метод get(), если необходимо удостовериться в наличии данных в БД.

14. Что вы знаете о кэширование в Hibernate? Объясните понятие кэш первого уровня в Hibernate?

Hibernate использует кэширование, чтобы сделать наше приложение быстрее. Кэш Hibernate может быть очень полезным в получении высокой производительности приложения при правильном использовании. Идея кэширования заключается в сокращении количества запросов к базе данных.

Кэш первого уровня Hibernate связан с объектом Session. Кэш первого уровня у Hibernate  включен по умолчанию и не существует никакого способа, чтобы его отключить. Однако Hibernate предоставляет методы, с помощью которых мы можем удалить выбранные объекты из кэша или полностью очистить кэш.
Любой объект закэшированный в session не будет виден другим объектам session. После закрытия объекта сессии все кэшированные объекты будут потеряны.

15. Как настроить кэш второго уровня в Hibernate с помощью EHCache?

EHCache является лучшим выбором для организации кэширования второго уровня в хибернейт. Для настройки второго уровня кэширования в хибернейт требуется выполнить несколько шагов.

  • Добавить зависимость hibernate-ehcache в проект.

  • Добавить несколько записей в конфигурационный файл Hibernate.

  • Создать файл конфигурации EHCache.

  • Использовать аннотацию @Cache и указание настройки стратегии кэширование над entity bean.

16. Каковы существуют различные состояния у entity bean?

  1. Transient: состояние, при котором объект никогда не был связан с какой-либо сессией и не является персистентностью. Этот объект находится во временном состоянии. Объект в этом состоянии может стать персистентным при вызове метода save(), persist() или saveOrUpdate(). Объект персистентности может перейти в transient состоянии после вызова метода delete().
  2. Persistent: когда объект связан с уникальной сессией он находится в состоянии persistent (персистентности). Любой экземпляр, возвращаемый методами get() или load() находится в состоянии persistent.
  3. Detached: если объект был персистентным, но сейчас не связан с какой-либо сессией, то он находится в отвязанном (detached) состоянии. Такой объект можно сделать персистентным используя методы update(), saveOrUpdate(), lock() или replicate(). Состояния transient или detached так же могут перейти в состояние persistent как новый объект персистентности после вызова метода merge().

17. Как используется вызов метода Hibernate Session merge()?

Hibernate merge() может быть использован для обновления существующих значений, однако этот метод создает копию из переданного объекта сущности и возвращает его. Возвращаемый объект является частью контекста персистентности и отслеживает любые изменения, а переданный объект не отслеживается.

18. В чем разница между Hibernate save(), saveOrUpdate() и persist()?

Hibernate save() используется для сохранения сущности в базу данных. Проблема с использованием метода save() заключается в том, что он может быть вызван без транзакции. А следовательно если у нас имеется отображение нескольких объектов, то только первичный объект будет сохранен и мы получим несогласованные данные. Также save() немедленно возвращает сгенерированный идентификатор.

Hibernate persist() аналогичен save() с транзакцией. persist() не возвращает сгенерированный идентификатор сразу.

Hibernate saveOrUpdate() использует запрос для вставки или обновления, основываясь на предоставленных данных. Если данные уже присутствуют в базе данных, то будет выполнен запрос обновления. Метод saveOrUpdate() можно применять без транзакции, но это может привести к аналогичным проблемам, как и в случае с методом save().

19. Что произойдет, если будет отсутствовать конструктор без аргументов у Entity Bean?

Hibernate использует рефлексию для создания экземпляров Entity бинов при вызове методов get() или load(). Для этого используется метод Class.newInstance(), который требует наличия конструктора без параметров. Поэтому, в случае его отсутствия, вы получите ошибку HibernateException.

20. В чем разница между sorted collection и ordered collection? Какая из них лучше?

При использовании алгоритмов сортировки из Collection API для сортировки коллекции используется сортированный список (sorted list). Для маленьких коллекций это не приводит к излишнему расходу ресурсов, но на больших коллекциях это может привести к потере производительности и ошибкам OutOfMemory. Так же entity бины должны реализовывать интерфейс Comparable или Comparator для работы с сортированными коллекциями.

При использовании фреймворка Hibernate для загрузки данных из базы данных мы можем применить Criteria API и команду order by для получения отсортированного списка (ordered list). Ordered list является лучшим выбором к sorted list, т.к. он использует сортировку на уровне базы данных. Она быстрее и не может привести к утечке памяти. Пример запроса к БД для получения ordered list:

21. Какие типы коллекций в Hibernate вы знаете?

  1. Bag
  2. Set
  3. List
  4. Array
  5. Map

22. Как реализованы Join’ы Hibernate?

Существует несколько способов реализовать связи в Hibernate.

  • Использовать ассоциации, такие как one-to-one, one-to-many, many-to-many.
  • Использовать в HQL запросе команду JOIN. Существует другая форма «join fetch«, позволяющая загружать данные немедленно (не lazy).
  • Использовать чистый SQL запрос с командой join.

23. Почему мы не должны делать Entity class как final?

Хибернейт использует прокси классы для ленивой загрузки данных (т.е. по необходимости, а не сразу). Это достигается с помощью расширения entity bean и, следовательно, если бы он был final, то это было бы невозможно. Ленивая загрузка данных во многих случаях повышает производительность, а следовательно важна.

24. Что вы знаете о HQL и каковы его преимущества?

Hibernate Framework поставляется с мощным объектно-ориентированным языком запросов — Hibernate Query Language (HQL). Он очень похож на SQL, за исключением, что в нем используются объекты вместо имен таблиц, что делает язык ближе к объектно-ориентированному программированию.

HQL является регистронезависимым, кроме использования в запросах имен java переменных и классов, где он подчиняется правилам Java. Например, SelECt то же самое, что и select, но ru.javastudy.MyClass отличен от  ru.javastudy.MyCLASS. Запросы HQL кэшируются (это как плюс так и минус).

Подробнее можете посмотреть в Hibernate — Hibernate Query (HQL) примеры: SELECT, INSERT, UPDATE, DELETE и в общем разделе Hibernate.

25. Что такое Query Cache в Hibernate?

Hibernate реализует область кэша для запросов resultset, который тесно взаимодействует с кэшем второго уровня Hibernate. Для подключения этой дополнительной функции требуется несколько дополнительных шагов в коде. Query Cache полезны только для часто выполняющихся запросов с повторяющимися параметрами. Для начала необходимо добавить эту запись в файле конфигурации Hibernate:

Уже внутри кода приложения для запроса применяется метод setCacheable(true), как показано ниже:

26. Можем ли мы выполнить нативный запрос SQL (sql native) в Hibernate?

С помощью использования SQLQuery можно выполнять чистый запрос SQL. В общем случае это не рекомендуется, т.к. вы потеряете все преимущества HQL (ассоциации, кэширование). Выполнить можно примерно так:

27. Назовите преимущества поддержки нативного sql в Hibernate.

Использование нативного SQL может быть необходимо при выполнении запросов к некоторым базам данных, которые могут не поддерживаться в Hibernate. Примером может служить некоторые специфичные запросы и «фишки» при работе с БД от Oracle.

28. Что такое Named SQL Query?

Hibernate поддерживает именованный запрос, который мы можем задать в каком-либо центральном месте и потом использовать его в любом месте в коде. Именованные запросы поддерживают как HQL, так и Native SQL. Создать именованный запрос можно с помощью JPA аннотаций @NamedQuery@NamedNativeQuery или в конфигурационном файле отображения (mapping files).

Hibernate — примеры именованных запросов NamedQuery.

29. Каковы преимущества Named SQL Query?

Именованный запрос Hibernate позволяет собрать множество запросов в одном месте, а затем вызывать их в любом классе. Синтаксис Named Query проверяется при создании session factory, что позволяет заметить ошибку на раннем этапе, а не при запущенном приложении и выполнении запроса. Named Query глобальные, т.е. заданные однажды, могут быть использованы в любом месте.

Однако одним из основных недостатков именованного запроса является то, что его очень трудно отлаживать (могут быть сложности с поиском места определения запроса).

30. Расскажите о преимуществах использования Hibernate Criteria API.

Hibernate Criteria API является более объектно-ориентированным для запросов, которые получают результат из базы данных. Для операций update, delete или других DDL манипуляций использовать Criteria API нельзя. Критерии используются только для выборки из базы данных в более объектно-ориентированном стиле.

Вот некоторые области применения Criteria API:

  • Criteria API поддерживает проекцию, которую мы можем использовать для агрегатных функций вроде sum(), min(), max() и т.д.
  • Criteria API может использовать ProjectionList для извлечения данных только из выбранных колонок.
  • Criteria API может быть использована для join запросов с помощью соединения нескольких таблиц, используя методы createAlias(), setFetchMode() и setProjection().
  • Criteria API поддерживает выборку результатов согласно условиям (ограничениям). Для этого используется метод add() с помощью которого добавляются ограничения (Restrictions).
  • Criteria API позволяет добавлять порядок (сортировку) к результату с помощью метода addOrder().

Hibernate — примеры Criteria. Обзор Hibernate Criteria API

 

к списку вопросов раздела JEE

Собеседование по Java EE — Hibernate Framework (вопросы и ответы). Часть 2.

Share Button
24
5530 Total Views 2 Views Today

Добавить комментарий