Глава 3. Конфигурирование

Оглавление
  1. 3.1. Программная конфигурация
  2. 3.2. Получение SessionFactory
  3. 3.3. Соединения JDBC
  4. 3.4. Необязательные свойства конфигурации
    1. 3.4.1. Диалекты SQL
    2. 3.4.2. Outer Join Fetching
    3. 3.4.3. Двоичные потоки
    4. 3.4.4. Кэш второго уровня и кэш запросов
    5. 3.4.5. Замена языка запроса
    6. 3.4.6. Статистика Hibernate
  5. 3.5. Логирование
  6. 3.6. Имплементация NamingStrategy
  7. 3.7. Имплементация PersisterClassProvider
  8. 3.8. XML-файл конфигурации
  9. 3.9. Интеграция на сервер приложений Java EE
    1. 3.9.1. Конфигурация стратегии транзакций
    2. 3.9.2. JNDI-связанный SessionFactory
    3. 3.9.3. Управление текущим контекстом сессии   помощью JTA

Hibernate предназначен для работы во многих различных средах, поэтому для него существует широкий диапазон параметров конфигурации. Большинство из них имеют разумные значения по умолчанию, а Hibernate распространяется с примером файла hibernate.properties в etc/, который отображает различные параметры. Просто подставьте пример файла в свой classpath и настройте его в соответствии с вашими потребностями.

3.1. Программная конфигурация

Экземпляр org.hibernate.cfg.Configuration представляет собой полный набор отображений типов Java приложения для базы данных SQL. Конфигурация org.hibernate.cfg.Configuration используется для создания неизменяемого org.hibernate.SessionFactory. Отображения компилируются из различных XML-файлов.

Вы можете получить экземпляр org.hibernate.cfg.Configuration, создав его непосредственно и указав XML-файлы отображений. Если файлы отображений находятся в classpath, используйте addResource(). Например:

Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");

Альтернативный способ — указать отображаемый класс и позволить Hibernate найти XML-файлы отображений:

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);

Затем Hibernate будет искать файлы отображаемый с именами /org/hibernate/auction/Item.hbm.xml и /org/hibernate/auction/Bid.hbm.xml в classpath. Такой подход исключает любые жестко заданные имена файлов.

org.hibernate.cfg.Configuration также позволяет указать свойства конфигурации. Например:

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");

Это не единственный способ передать свойства конфигурации в Hibernate. Некоторые альтернативные варианты включают:

  1. Передачу экземпляра java.util.Properties в Configuration.setProperties().
  2. Размещение файла с именем hibernate.properties в корне classpath.
  3. Установка System-свойств с использование java -Dproperty=value.
  4. Включение элементов <property> в файл hibernate.cfg.xml (обсуждается ниже).

Самый простой способ из перечисленных - hibernate.properties.

Конфигурация org.hibernate.cfg.Configuration содержит стартовые настройки, которые будут отброшены после создания SessionFactory.

3.2. Получение SessionFactory

Когда все отображения были проанализированы с помощью org.hibernate.cfg.Configuration, приложение должно получить фабрику для экземпляров org.hibernate.Session. Эта фабрика предназначена для совместного использования всеми прикладными потоками:

SessionFactory sessions = cfg.buildSessionFactory();

Hibernate позволяет вашему приложению создавать экземпляры более чем одного org.hibernate.SessionFactory. Это полезно, если вы используете несколько баз данных.

3.3. Соединения JDBC

Желательно, чтобы org.hibernate.SessionFactory создавал и объединял в пул JDBC-соединения для вас. Такой подход позволяет очень просто открыть org.hibernate.Session:

Session session = sessions.openSession(); // открыть новый Session

После запуска задачи, требующей доступа к базе данных, соединение JDBC будет получено из пула.

Прежде чем вы сможете это сделать, нужно передать некоторые свойства соединения JDBC в Hibernate. Все имена и семантика свойств Hibernate определены в классе org.hibernate.cfg.Environment. Ниже перечислены наиболее важные настройки для конфигурации соединения JDBC.

Таблица 3.1. Свойства Hibernate JDBC

Имя свойства Назначение
hibernate.connection.driver_class JDBC driver class
hibernate.connection.url JDBC URL
hibernate.connection.username имя пользователя JDBC
hibernate.connection.password пароль пользователя JDBC
hibernate.connection.pool_size максимальное число соединений в пуле

Алгоритм объединения пула Hibernate довольно рудиментарный. Он призван помочь вам начать работу и не предназначен для использования в продакшене или даже для тестирования производительности. Вы должны использовать сторонний пул для обеспечения максимальной производительности и стабильности. Просто замените свойство hibernate.connection.pool_size с конкретными настройками пула соединений. Это отключит внутренний пул Hibernate. Например, вы можете использовать c3p0.

C3P0 — пул соединений JDBC с открытым исходным кодом, распространяемый вместе с Hibernate в каталоге lib. Hibernate будет использовать свой org.hibernate.connection.C3P0ConnectionProvider для объединения пулов если вы установите свойства hibernate.c3p0.*. Если вы хотите использовать Proxool, обратитесь к упакованным hibernate.properties и веб-сайту Hibernate за дополнительной информацией.

Ниже приведен пример файла hibernate.properties для c3p0:

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect

Для использования внутри сервера приложений вы почти всегда должны настраивать Hibernate для получения соединений с помощью javax.sql.Datasource, зарегистрированного в JNDI. Вам нужно будет установить хотя бы одно из следующих свойств:

Таблица 3.2. Свойства Hibernate Datasource

Имя свойства Назначение
hibernate.connection.datasource имя datasource JNDI
hibernate.jndi.url URL провайдера JNDI (необязательный)
hibernate.jndi.class Класс JNDI InitialContextFactory (необязательный)
hibernate.connection.username имя пользователя бд (необязательный)
hibernate.connection.password пароль пользователя бд (необязательный)

Ниже приведен пример файла hibernate.properties для сервера приложений, предоставляемого источником данных JNDI:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect

Соединения JDBC, полученные из источника данных JNDI, будут автоматически участвовать в транзакциях, управляемых контейнером сервера приложений.

Произвольные свойства соединения могут быть заданы путем добавления «hibernate.connection» к имени свойства соединения. Например, вы можете указать свойство соединения charSet с помощью hibernate.connection.charSet.

Вы можете определить свою собственную стратегию плагина для получения соединений JDBC, реализовав интерфейс org.hibernate.connection.ConnectionProvider и указав свою пользовательскую реализацию через свойство hibernate.connection.provider_class.

3.4. Необязательные свойства конфигурации

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

Внимание

Некоторые из этих свойств являются исключительно «системными». Свойства системного уровня могут быть установлены только через java -Dproperty=value или hibernate.properties. Они не могут быть установлены другими способами, описанными выше.

Таблица 3.3. Свойства конфигурации Hibernate

Имя свойства Назначение
hibernate.dialect Имя класса Hibernate org.hibernate.dialect.Dialect, которое позволяет Hibernate генерировать SQL, оптимизированный для конкретной реляционной базы данных.

пример: full.classname.of.Dialect

В большинстве случаев Hibernate самостоятельно сможет выбрать правильный org.hibernate.dialect.Dialect реализованный на основе JDBC metadata, возвращенного драйвером JDBC.
hibernate.show_sql Пишет все инструкции SQL в консоль. Это альтернатива установке значения debug свойства org.hibernate.SQL

значения: true | false

hibernate.format_sql Форматированный вывод SQL в лог и консоль.

значения: true | false

hibernate.default_schema Квалифицировать имена неквалифицированных таблиц с данными схемы/табличного пространства в сгенерированном SQL.

пример: SCHEMA_NAME

hibernate.default_catalog Определяет имена неквалифицированных таблиц с данным каталогом в сгенерированный SQL.

пример: CATALOG_NAME

hibernate.session_factory_name org.hibernate.SessionFactory автоматически привязывается к этому имени в JNDI после его создания.

пример: jndi/composite/name

hibernate.max_fetch_depth Устанавливает максимальную «глубину» для outer join дерева выборки однотипных ассоциаций (один к одному, много-к-одному). 0 отключает outer join выборку.

значения: рекоменддуемые значения от 0 до 3

hibernate.default_batch_fetch_size Устанавливает размер по умолчанию для пакетной выборки Hibernate.

значения: рекоменддуемые значения 4, 8, 16

hibernate.default_entity_mode Устанавливает режим по умолчанию для представления сущности для всех сессий, открытых из этого SessionFactory. По умолчанию используется pojo.

значения: dynamic-map|pojo

hibernate.order_updates Заставляет Hibernate упорядочивать обновления SQL по значению первичного ключа обновляемых элементов. Это приводит к меньшему количеству блокировок транзакций в высококонкурентных системах

значения: true | false

hibernate.generate_statistics Если включено, Hibernate будет собирать статистику, полезную для настройки производительности.

значения: true | false

hibernate.use_identifier_rollback Если включено, сгенерированные свойства идентификатора будут сброшены до значений по умолчанию, когда объекты будут удалены.

значения: true | false

hibernate.use_sql_comments Если включено, Hibernate будет генерировать комментарии внутри SQL, для более легкой отладки по умолчанию используется значение false.

значения: true | false

hibernate.id.new_generator_mappings Настройка применима при использовании @GeneratedValue. Она указывает, используются ли новые реализации IdentifierGenerator для javax.persistence.GenerationType.AUTO, javax.persistence.GenerationType.TABLE и javax.persistence.GenerationType.SEQUENCE. По умолчанию false для сохранения обратной совместимости.

значения: true | false

Заметка

Мы рекомендуем во всех новых проектах, которые используют @GeneratedValue, также установить hibernate.id.new_generator_mappings=true, поскольку новые генераторы более эффективны и ближе к семантике спецификации JPA 2. Однако они обратно не совместимы с существующими базами данных (если для генерации идентификатора используется последовательность или таблица).

Таблица 3.4. Свойства JDBC и соединений в Hibernate

Имя свойства Назначение
hibernate.jdbc.fetch_size Ненулевое значение определяет размер выборки JDBC (вызывает Statement.setFetchSize()).
hibernate.jdbc.batch_size Ненулевое значение включает использование пакетного обновления JDBC2 в Hibernate.

значения: рекоменддуемые значения между 5 и 30

hibernate.jdbc.batch_versioned_data Установите для этого свойства значение true, если ваш драйвер JDBC возвращает правильные подсчеты строк из executeBatch(). Обычно включение этой опции безопасно. Затем Hibernate будет использовать пакетный DML для автоматически версионифицированных данных. По умолчанию false.

значения: true | false

hibernate.jdbc.factory_class Выберите пользовательский org.hibernate.jdbc.Batcher. В большинстве приложений это свойство конфигурации не требуется.

пример: classname.of.BatcherFactory

hibernate.jdbc.use_scrollable_resultset Позволяет использовать JDBC2 прокручиваемые (scrollable) результаты (resultsets) с помощью Hibernate. Это свойство необходимо только при использовании пользовательских JDBC-соединений. В противном случае Hibernate использует метаданные соединения.

значения: true | false

hibernate.jdbc.use_streams_for_binary Использует потоки при записи/чтении для типов binary или serializable в/из JDBC. *свойство системного уровня*

значения: true | false

hibernate.jdbc.use_get_generated_keys Позволяет использовать JDBC3 PreparedStatement.getGeneratedKeys() для извлечения инициализированных ключей после вставки. Требуется драйвер JDBC3+ и JRE1.4+, установите значение false если у вашего драйвера проблемы с генераторами идентификаторов Hibernate. По умолчанию он пытается определить возможности драйвера, используя метаданные соединения.

значения: true | false

hibernate.connection.provider_class Имя класса настраиваемого org.hibernate.connection.ConnectionProvider, который предоставляет соединения JDBC для Hibernate.

пример: classname.of.ConnectionProvider

hibernate.connection.isolation Устанавливает уровень изоляции транзакции JDBC. Проверьте java.sql.Connection для значимых значений, но обратите внимание, что большинство баз данных не поддерживают все уровни изоляции, а некоторые определяют дополнительные, нестандартные уровени изоляции.

значения: 1, 2, 4, 8

hibernate.connection.autocommit Включает автофиксирование (autocommit) для объединённых (pooled) соединений JDBC (Использовать не рекомендуется).

значения: true | false

hibernate.connection.release_mode Указывает, когда Hibernate должен освобождать JDBC-соединения. По умолчанию соединение JDBC выполняется до тех пор, пока сессия не будет явно закрыта или отключена. Для источника данных (datasource) JTA сервера приложений используйте after_statement для намерернного освобожения соединений после каждого вызова JDBC. Для не-JTA-соединения часто бывает целесообразно освободить соединение в конце каждой транзакции, используя after_transaction. auto выберет after_statement для стратегий транзакций JTA и CMT и after_transaction для стратегии транзакций JDBC. <и>e.g. auto (default) |

значения: auto по умолчанию | on_close | after_transaction | after_statement

Этот параметр влияет только на сессии, возвращённые SessionFactory.openSession. Для сессий, полученных с помощью SessionFactory.getCurrentSession, реализация CurrentSessionContext, настроенная для использования, управляет режимом освобождения соединения. См. Параграф «2.2. Контекстные сессии»
hibernate.connection.<propertyName> Передать свойство JDBC <propertyName> и его значение в DriverManager.getConnection().
hibernate.jndi.<propertyName> Передать свойство <propertyName> и его значение в JNDI InitialContextFactory.

Таблица 3.5. Свойства кэша в Hibernate

Имя свойства Назначение
hibernate.cache.provider_class Имя класса пользовательского CacheProvider.

пример: classname.of.CacheProvider

hibernate.cache.use_minimal_puts Оптимизирует работу кэша второго уровня для минимизации операций записи, за счет более частых чтений. Этот параметр наиболее полезен для кластеризованных кэшей, В Hibernate — по умолчанию включён для кластеризованных реализаций кэша.

значения: true | false

hibernate.cache.use_query_cache Включает кэш запросов. Индивидуальные запросы по-прежнему должны быть установлены с возможностью кэширования.

значения: true | false

hibernate.cache.use_second_level_cache Может использоваться для полного отключения кэша второго уровня, который по умолчанию включён для классов, которые определяют отображение <cache>.

значения: true | false

hibernate.cache.query_cache_factory Имя класса пользовательского интерфейса QueryCache. По умолчанию соответствует встроенному StandardQueryCache.

пример: classname.of.QueryCache

hibernate.cache.region_prefix Префикс используется для имен регистров второго уровня.

пример: prefix

hibernate.cache.use_structured_entries Заставляет Hibernate хранить данные в кэше второго уровня в более удобном для пользователя формате.

значения: true | false

hibernate.cache.auto_evict_collection_cache Включает автоматическое "вытеснение" кэша коллекции двунаправленной ассоциации, когда элемент в коллекции ManyToOne добавляется/обновляется/удаляется без надлежащего управления изменениями на стороне OneToMany.

значения: true | false

hibernate.cache.default_cache_concurrency_strategy Настройка, используемая для указания имени по умолчанию для org.hibernate.annotations.CacheConcurrencyStrategy, когда используется либо @Cacheable, либо @Cache. @Cache(strategy=«..») используется для переопределения этого значения по умолчанию.

Таблица 3.6. Свойства транзакций в Hibernate

Имя свойства Назначение
hibernate.transaction.factory_class Имя класса TransactionFactory для использования с Hibernate Transaction API (по умолчанию используется JDBCTransactionFactory).

пример: classname.of.TransactionFactory

jta.UserTransaction Имя JNDI, используемое JTATransactionFactory для получения JTA UserTransaction с сервера приложений.

пример: jndi/composite/name

hibernate.transaction.manager_lookup_class Имя класса TransactionManagerLookup. Это необходимо, если включено кэширование на уровне JVM или при использовании hilo-генератора в среде JTA. e.g.

пример: classname.of.TransactionManagerLookup

hibernate.transaction.flush_before_completion Если этот параметр включён, сессия будет автоматически очищаться во время фазы "До завершения транзакции". Предпочтительным является встроенное и автоматическое управление контекстом сессии. См. Параграф «2.2. Контекстные сессии».

значения: true | false

hibernate.transaction.auto_close_session Если этот параметр включён, сессия будет автоматически закрываться во время фазы "После завершения транзакции". Предпочтительным является встроенное и автоматическое управление контекстом сессии. См. Параграф «2.2. Контекстные сессии».

значения: true | false

Таблица 3.7. Прочие свойства

Имя свойства Назначение
hibernate.current_session_context_class Поставьте индивидуальную стратегию для определения «текущей» сессии. См. Параграф «2.2. Контекстные сессии». для получения дополнительной информации о встроенных стратегиях.

значения: jta | thread | managed | custom.Class

hibernate.query.factory_class Выбирает реализацию парсера HQL.

пример: org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory или org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory

hibernate.query.substitutions Используется для отображения из токенов в запросах Hibernate в SQL-токены (например, токены могут быть именами функций или букв). пример: hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC
hibernate.hbm2ddl.auto Автоматически проверяет или экспортирует DDL схемы в базу данных когда SessionFactory создан. С помощью create-drop схема базы данных будет удалена когда SessionFactory будет закрыт явно.

значения: validate | update | create | create-drop

hibernate.hbm2ddl.import_files

Отделяемые запятыми имена необязательных файлов, содержащих SQL-выражения DML, выполняемые во время создания SessionFactory. Это полезно для тестирования или демонстрации: добавив инструкции INSERT, например, вы можете заполнить свою базу данных минимальным набором данных при ее развёртывании.

Порядок файлов имеет значение, операторы в файлах выполняются перед операциями следующих файлов. Эти инструкции выполняются если схема создана, т. е. если hibernate.hbm2ddl.auto настроен на create или create-drop.

пример: /humans.sql,/dogs.sql

hibernate.hbm2ddl.import_files_sql_extractor

Имя класса пользовательского ImportSqlCommandExtractor (по умолчанию используется встроенный SingleLineSqlCommandExtractor). Это полезно для реализации выделенного парсера, который извлекает отдельные инструкции SQL из каждого файла импорта. Hibernate предоставляет также MultipleLinesSqlCommandExtractor, который поддерживает инструкции/комментарии и цитируемые строки, распредёленные по нескольким строкам (обязательная точка с запятой в конце каждого оператора).

пример: classname.of.ImportSqlCommandExtractor

hibernate.bytecode.use_reflection_optimizer

Включает использование манипуляций с байт-кодом вместо рефлексии во время выполнения (runtime). Это свойство системного уровня и не может быть установлено в файле hibernate.cfg.xml. Иногда рефлексия может быть полезна при поиске и устранении неисправностей. Hibernate всегда требует javassist, даже если вы отключите оптимизатор.

значения: true | false

hibernate.bytecode.provider

На данный момент javassist является единственным поддерживаемым провайдером байт-кода.

значения: javassist

3.4.1. Диалекты SQL

Всегда устанавливайте свойство hibernate.dialect в соответствующий подкласс org.hibernate.dialect.Dialect для вашей базы данных. Если вы укажете диалект Hibernate будет использовать разумные значения по умолчанию для некоторых других свойств, перечисленных выше. Это означает, что вам не нужно будет указывать их вручную.

Таблица 3.8. Hibernate SQL диалекты (hibernate.dialect)

RDBMS Диалект
CUBRID 8.3 and later org.hibernate.dialect.CUBRIDDialect
DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
Firebird org.hibernate.dialect.FirebirdDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
H2 org.hibernate.dialect.H2Dialect
HyperSQL (HSQL) org.hibernate.dialect.HSQLDialect
Informix org.hibernate.dialect.InformixDialect
Ingres org.hibernate.dialect.IngresDialect
Ingres 9 org.hibernate.dialect.Ingres9Dialect
Ingres 10 org.hibernate.dialect.Ingres10Dialect
Interbase org.hibernate.dialect.InterbaseDialect
InterSystems Cache 2007.1 org.hibernate.dialect.Cache71Dialect
JDataStore org.hibernate.dialect.JDataStoreDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Microsoft SQL Server 2000 org.hibernate.dialect.SQLServerDialect
Microsoft SQL Server 2005 org.hibernate.dialect.SQLServer2005Dialect
Microsoft SQL Server 2008 org.hibernate.dialect.SQLServer2008Dialect
Microsoft SQL Server 2012 org.hibernate.dialect.SQLServer2012Dialect
Mimer SQL org.hibernate.dialect.MimerSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
MySQL5 org.hibernate.dialect.MySQL5Dialect
MySQL5 with InnoDB org.hibernate.dialect.MySQL5InnoDBDialect
Oracle 8i org.hibernate.dialect.Oracle8iDialect
Oracle 9i org.hibernate.dialect.Oracle9iDialect
Oracle 10g and later org.hibernate.dialect.Oracle10gDialect
Oracle TimesTen org.hibernate.dialect.TimesTenDialect
Pointbase org.hibernate.dialect.PointbaseDialect
PostgreSQL 8.1 org.hibernate.dialect.PostgreSQL81Dialect
PostgreSQL 8.2 org.hibernate.dialect.PostgreSQL82Dialect
PostgreSQL 9 and later org.hibernate.dialect.PostgreSQL9Dialect
Progress org.hibernate.dialect.ProgressDialect
SAP DB org.hibernate.dialect.SAPDBDialect
SAP HANA (column store) org.hibernate.dialect.HANAColumnStoreDialect
SAP HANA (row store) org.hibernate.dialect.HANARowStoreDialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase 11 org.hibernate.dialect.Sybase11Dialect
Sybase ASE 15.5 org.hibernate.dialect.SybaseASE15Dialect
Sybase ASE 15.7 org.hibernate.dialect.SybaseASE157Dialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Teradata org.hibernate.dialect.TeradataDialect
Unisys OS 2200 RDMS org.hibernate.dialect.RDMSOS2200Dialect

3.4.2. Outer Join Fetching

Если ваша база данных поддерживает внешние соединения (outer joins) типа ANSI, Oracle или Sybase, outer join fetching (выборка по внешнему соединению) часто увеличивает производительность, ограничивая количество обращений в ту или иную базу данных за счет большей работы, выполняемой самой базой данных. Выборка по внешнему соединению (outer join fetching) позволяет получить целый граф объектов, соединённых ассоциациями «один-ко-многим», «многие-ко-многим» и «один-к-одному», которые будут извлекаться в одном SQL SELECT.

Выборку по внешнему соединению (outer join fetching) можно отключить глобально, установив свойство hibernate.max_fetch_depth равным 0. Параметр 1 или выше позволяет использовать выборку по внешнему соединению для ассоциаций «один к одному» и «многие-к-одному», которые были отображены с помощью fetch=«join».

Дополнительную информацию см. в разделе 20.1 «Стратегии выборки».

3.4.3. Двоичные потоки (binary streams)

Oracle ограничивает размер массивов типа byte, которые могут быть переданы в и/или из его драйвера JDBC. Если вы хотите использовать большие экземпляры типов byte или serializable, вы должны включить hibernate.jdbc.use_streams_for_binary. Это свойство системного уровня.

3.4.4. Кэш второго уровня и кэш запросов

Свойства с префиксом hibernate.cache позволяют использовать систему кэширования второго уровня с областью видимости процесса или кластера. Дополнительную информацию см. в разделе 20.2 «Кэш второго уровня».

3.4.5. Замена языка запроса

Вы можете определить новые токены запросов Hibernate, используя hibernate.query.substitutions. Например:

hibernate.query.substitutions true=1, false=0

Это приведет к тому, что токены true и false будут переведены в целочисленные (integer) литералы в сгенерированном SQL.

hibernate.query.substitutions toLowercase=LOWER

Это позволит вам переименовать SQL функцию LOWER.

3.4.6. Статистика Hibernate

Если вы включите hibernate.generate_statistics, то Hibernate предоставит ряд показателей, которые полезны при настройке запущенной системы через SessionFactory.getStatistics(). Также для отображения этих статистических данных Hibernate может быть настроен через JMX. Прочтите об интерфейсах org.hibernate.stats в Javadoc для получения дополнительной информации.

3.5. Логирование

Важно

Полностью устарело. Hibernate использует JBoss Logging, начиная с 4.0. Документация появится как только мы перенесём этот контент в Руководство разработчика.

Hibernate использует Simple Logging Facade for Java (SLF4J) для логирования различных системных событий. SLF4J может направлять вывод журнала в несколько фреймворков регистрации (NOP, Simple, log4j v1.2, JDK 1.4 logging, JCL или logback) в зависимости от выбранного вами. Чтобы настроить ведение журнала вам понадобится slf4j-api.jar в вашем classpath вместе с файлом jar для выбранного вами логгера (slf4j-log4j12.jar в случае Log4J). Более подробную информацию см. в документации SLF4J. Для использования Log4j вам также необходимо поместить файл log4j.properties в classpath. Пример файла свойств распространяется вместе с Hibernate в каталоге src/.

Рекомендуется ознакомиться с сообщениями журнала Hibernate. Было сделано много работы, чтобы сделать журнал Hibernate максимально подробным, не делая его нечитаемым. Наиболее интересными категориями журналов являются:

Таблица 3.9. Категории лога Hibernate

Категория Функция
org.hibernate.SQL Записывать все инструкции SQL DML во время их выполнения
org.hibernate.type Записывать все JDBC параметры
org.hibernate.tool.hbm2ddl Записывать все инструкции SQL DDL во время их выполнения
org.hibernate.pretty Записывать состояние всех сущностей (не более 20 сущностей), связанных с session во время очистки (flush)
org.hibernate.cache Записывать всю активность кэша второго уровня
org.hibernate.transaction Записывать всю активность, связанную с транзакциями
org.hibernate.jdbc Записывать все ресурсы JDBC
org.hibernate.hql.internal.ast.AST Записывать все HQL и SQL AST во вермя парсинга запросов
org.hibernate.secure Записывать все запросы авторизации JAAS
org.hibernate Записывать всё. Это огромное количество имформации, но полезно для поиска и устранения проблем

При разработке приложений с Hibernate вы почти всегда должны работать с включённым debug для категории org.hibernate.SQL или установить свойство hibernate.show_sql в true.

3.6. Имплементация NamingStrategy

Интерфейс org.hibernate.cfg.NamingStrategy позволяет указать «стандарт именования» для объектов базы данных и элементов схемы.

Вы можете предоставить правила для автоматического создания идентификаторов базы данных из идентификаторов Java или для обработки «логических» столбцов и имен таблиц, указанных в файле отображения, в «физические» имена таблиц и столбцов. Эта функция помогает уменьшить многословие файла отображения, устраняя повторяющийся куски (например, префиксы TBL_). Стратегия по умолчанию, используемая Hibernate, минимальна.

Вы можете указать другую стратегию, вызвав Configuration.setNamingStrategy() перед добавлением отображений:

SessionFactory sf = new Configuration()
    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
    .addFile("Item.hbm.xml")
    .addFile("Bid.hbm.xml")
    .buildSessionFactory();

org.hibernate.cfg.ImprovedNamingStrategy — это встроенная стратегия, которая может быть полезной отправной точкой для некоторых приложений.

3.7. Имплементация PersisterClassProvider

Вы можете настроить реализацию persister, используемую для сохранения ваших сущностей и коллекций:

Каждый последующий элемент в списке выше по приоритету.

Вы можете передать экземпляр PersisterClassProvider в объект Configuration.

SessionFactory sf = new Configuration()
    .setPersisterClassProvider(customPersisterClassProvider)
    .addAnnotatedClass(Order.class)
    .buildSessionFactory();

Методы провайдера класса persister при возврате непустого класса persister переопределяют константы Hibernate по умолчанию. Имя сущности или роль коллекции передаются методам. Это хороший способ централизовать основную логику persist-приложений вместо того, чтобы распространять их на каждом отображении сущности или коллекции.

3.8. XML-файл конфигурации

Альтернативный подход к настройке — указать полную конфигурацию в файле с именем hibernate.cfg.xml. Этот файл может использоваться как замена файла hibernate.properties или, если они присутствуют, для переопределения свойств.

Файл конфигурации XML по умолчанию должен находиться в корне вашего CLASSPATH. Вот пример:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!-- a SessionFactory instance listed as /jndi/name -->
    <session-factory
        name="java:hibernate/SessionFactory">
        <!-- properties -->
        <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">false</property>
        <property name="transaction.factory_class">
            org.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="jta.UserTransaction">java:comp/UserTransaction</property>
        <!-- mapping files -->
        <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
        <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
        <!-- cache settings -->
        <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
        <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
        <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
    </session-factory>
</hibernate-configuration>

Преимуществом этого подхода является экстернализация имен файлов отображения для конфигурации. hibernate.cfg.xml также более удобен, если вам нужно настроить кэш-память Hibernate. Это ваш выбор использовать либо hibernate.properties, либо hibernate.cfg.xml. Оба они эквивалентны, за исключением вышеупомянутых преимуществ использования синтаксиса XML.

С конфигурацией XML запуск Hibernate прост:

SessionFactory sf = new Configuration().configure().buildSessionFactory();

Вы можете выбрать другой файл конфигурации XML, используя:

SessionFactory sf = new Configuration()
    .configure("catdb.cfg.xml")
    .buildSessionFactory();

3.9. Интеграция на сервер приложений Java EE

Hibernate имеет следующие точки интеграции для инфраструктуры J2EE:

В зависимости от вашей среды вам может потребоваться установить для параметра конфигурации hibernate.connection.aggressive_release значение true, если на вашем сервере приложений отображаются исключения «connection containment».

3.9.1. Конфигурация стратегии транзакций

API сессии Hibernate не зависит от любой системы разделения транзакций в вашей архитектуре. Если вы позволяете Hibernate использовать JDBC напрямую через пул соединений, вы можете начинать и заканчивать свои транзакции вызовами JDBC API. Если вы запустили сервер приложений J2EE, вы можете использовать транзакции, управляемые бинами, и при необходимости обращаться к API JTA и UserTransaction.

Чтобы переносить код между этими двумя (и другими) средами, мы рекомендуем дополнительный Hibernate Transaction API, который обертывает и скрывает базовую систему. Вы должны указать фабричный класс для экземпляров транзакций, установив свойство конфигурации Hibernate hibernate.transaction.factory_class.

Существуют три стандартных или встроенных варианта:

org.hibernate.transaction.JDBCTransactionFactory

делегирует транзакции базе данных (JDBC) (по умолчанию)

org.hibernate.transaction.JTATransactionFactory

делегирует транзакции, управляемые контейнером, если в этом контексте выполняется существующая транзакция (например, метод бина сессии (session) EJB). В противном случае запускается новая транзакция и используются транзакции, управляемые бином.

org.hibernate.transaction.CMTTransactionFactory

делегирует JTA транзакциям, управляемым контейнерами

Вы также можете определить свои собственные стратегии транзакций (например для сервиса транзакций CORBA).

Некоторые функции в Hibernate (кэш второго уровня, контекстные сессии с JTA и т. д.) требуют доступа к JTA TransactionManager в управляемой среде. На сервере приложений, поскольку J2EE не стандартизирует единый механизм, вы должны указать, как Hibernate должен получить ссылку на TransactionManager:

Таблица 3.10. JTA TransactionManagers

Фабрика транзакций Сервер приложений
org.hibernate.transaction.JBossTransactionManagerLookup JBoss AS
org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookup Orion
org.hibernate.transaction.ResinTransactionManagerLookup Resin
org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
org.hibernate.transaction.BESTransactionManagerLookup Borland ES
org.hibernate.transaction.JBossTSStandaloneTransactionManagerLookup JBoss TS используется отдельно (вне JBoss AS и JNDI сред). Для работы с org.jboss.jbossts:jbossjta:4.11.0.Final

3.9.2. JNDI-связанный SessionFactory

Связанный с JNDI Hibernate SessionFactory может упростить функцию поиска фабрики и создать новые сессии (Session). Однако это не связано с источником данных (Datasource), связанным с JNDI; оба просто используют один и тот же реестр.

Если вы хотите связать SessionFactory с пространством имен JNDI, укажите имя (например, java:hibernate/SessionFactory), используя свойство hibernate.session_factory_name. Если это свойство опущено SessionFactory не будет привязан к JNDI. Это особенно полезно в средах с реализацией JNDI только для чтения (например, в Tomcat).

При привязке SessionFactory к JNDI, Hibernate будет использовать значения hibernate.jndi.url, hibernate.jndi.class для создания исходного контекста. Если они не указаны, будет использоваться InitialContext по умолчанию.

Hibernate автоматически поместит SessionFactory в JNDI после вызова cfg.buildSessionFactory(). Это означает, что у вас будет этот вызов в коде запуска или классе утилиты в вашем приложении, если только вы не используете JMX-развертывание с HibernateService (это более подробно обсуждается позже).

Если вы используете JNDI SessionFactory, EJB или любой другой класс, вы можете получить SessionFactory с помощью поиска JNDI.

Рекомендуется привязать SessionFactory к JNDI в управляемой среде и использовать статический singleton. Чтобы защитить ваш код приложения от этих деталей, мы также рекомендуем скрыть фактический код поиска для SessionFactory в вспомогательном классе, например HibernateUtil.getSessionFactory(). Обратите внимание, что такой класс также является удобным способом запуска Hibernate — см. главу 1.

3.9.3. Управление текущим контекстом сессии с помощью JTA

Самый простой способ обработки сессий (Sessions) и транзакций  — это автоматическое управление «текущем» сессией (Session) Hibernate. Обсуждение контекстных сессии см. в параграфе «2.2. Контекстные сессии». Используйте контекст сессии (Session) «jta», если сессия (Session) Hibernate не связана с текущей транзакцией JTA. Он будет запущен и связан с этой транзакцией JTA при первом вызове sessionFactory.getCurrentSession(). Сессии (Sessions), полученные через getCurrentSession() в контексте «jta», автоматически устанавливаются до завершения транзакции, закрываются после завершения транзакции и принудительно освобождают соединения JDBC после каждой инструкции. Это позволяет сеесиям (Sessions) управлять жизненным циклом транзакции JTA, к которой она привязана, что сохраняет код пользователя "чистым" от кода управления. Ваш код может либо использовать JTA программно через UserTransaction, либо (рекомендуется для переносимого кода) использовать Hibernate Transaction API для установки границ транзакций. Если вы запускаете контейнер EJB предпочтительной является разделение транзакций с CMT.