Так как Hibernate разработан для эксплуатации в различных окружениях, существует множество конфигурационных параметров. К счастью, у большинства имеются разумные значения по умолчанию, и Hibernate распространяется с примером настроечного файла hibernate.properties, демострирующим различные опции. Обычно, вам нужно только подредактировать этот файл и положить его в classpath.
Экземпляр класса net.sf.hibernate.cfg.Configuration представляет весь набор мэппингов/отображений типов Java приложения к реляционной базе данных. Экземпляр класса Configuration используется для построения неизменяемой (immutable) SessionFactory. Отображения/мэппинги собираются из различных XML-файлов (XML mapping files).
Экземпляр класса Configuration можно получить путем прямой инициализации. Вот пример настройки хранилища данных из отображений/мэппингов, описанных в двух конфигурационных XML-файлах (в classpath):
Configuration cfg = new Configuration() .addFile("Item.hbm.xml") .addFile("Bid.hbm.xml");
Загрузить файл отображения (mapping file), используя getResourceAsStream() -- другой (иногда даже лучший) способ:
Configuration cfg = new Configuration() .addClass(org.hibernate.auction.Item.class) .addClass(org.hibernate.auction.Bid.class);
В этом случае Hibernate ищет в classpath файлы отображения/мэппингов, названные /org/hibernate/autcion/Item.hbm.xml и /org/hibernate/autcion/Bid.hbm.xml. Этот подход устраняет любые жестко закодированные имена файлов.
Экземпляр класса Configuration также специфицирует различные опциональные свойства:
Properties props = new Properties(); ... Configuration cfg = new Configuration() .addClass(org.hibernate.auction.Item.class) .addClass(org.hibernate.auction.Bid.class) .setProperties(props);
Экземпляр класса Configuration задуман как объект времени конфигурации (configuration-time): создается во время конфигурации и уничтожается как только построен экземпляр класса SessionFactory.
Когда экземпляр класса Configuration разберет (parse) все отображения/мэппинги, приложение получает фабрику (factory) для экземпляров класса Session. Эта фабрика должна быть распределена (shared) между всеми потоками приложения:
SessionFactory sessions = cfg.buildSessionFactory();
Тем не менее, Hibernate дает возможность вашему приложению инстанциировать более одного класса SessionFactory, что очень полезно, если вы используете больше чем одну базу данных.
Класс SessionFactory может открывать экземпляр класса Session по JDBC соединению, осуществляемому пользователем. Эта схема дает возможность приложению осуществлять JDBC соединение когда угодно:
java.sql.Connection conn = datasource.getConnection(); Session session = sessions.openSession(conn); // do some data access work
Чтобы не открыть два параллельных экземпляра класса Session при одном JDBC соединении, необходимо быть внимательным!
В качестве альтернативы вы можете использовать JDBC-соединения, открытые SessionFactory. При конфигурации экземпляра SessionFactory, ему должны быть предоставлены свойства JDBC-соединений, одним из следующих способов:
Передайте экземпляр класса java.util.Properties методу Configuration.setProperties().
Поместите экземпляр класса hibernate.properties в корневой каталог classpath.
Установите Системные своства следующим способом java -Dproperty=value.
Используйте XML-элементы <property> в файле hibernate.cfg.xml (обсуждается ниже).
Используя этот подход, открыть экземпляр класса Session так же просто как:
Session session = sessions.openSession(); // open a new Session // do some data access work, a JDBC connection will be used on demand
Все имена и семантика свойств Hibernate указаны в классе net.sf.hibernate.cfg.Environment. Мы опишем наиболее важные установки для конфигурации JDBC соедининия.
Hibernate получает (и помещает в пул) соедининия, используя экземпляр класса java.sql.DriverManager, если вы утанавливаете следующие свойства:
Таблица 3.1. Hibernate JDBC-cвойства (Properties)
Имя свойства | Назначение |
---|---|
hibernate.connection.driver_class | класс JDBC-драйвера |
hibernate.connection.url | JDBC URL |
hibernate.connection.username | имя пользователя базы данных |
hibernate.connection.password | пароль пользователя базы данных |
hibernate.connection.pool_size | максимальное число соединений в пуле |
Собственный алгоритм помещения соединений в пул (connection pooling algorithm) у Hibernate довольно прост. Его назначение помочь пользователю как можно быстрее начать использовать Hibernate без дополнительных настроек и он не предназначен для использования в рабочих системах, а также для тестирования производительности. Используйте третьесторонний пул соединений для наилучшей производительности и стабильности, т.е. замените свойство hibernate.connection.pool_size определенными настройками пула соединений.
С3PO -- JDBC пул соединений с открытыми исходными кодами (open source connection pool), распространяемый вместе с Hibernate в каталоге lib. Hibernate будет использовать встроенный провайдер соединений C3P0ConnectionProvider для пула, если вы установите свойства hibernate.c3p0.*. Также существует встроенная поддержка для Apache DBCP и Proxool. Для того чтобы использовать DBCPConnectionProvider, вы должны установить свойства DBCP пула соединений hibernate.dbcp.*. Кэширование подговленных JDBC-выражений (prepared statement caching) включается (очень рекомендуем) если установлены следующие свойства hibernate.dbcp.ps.* (DBCP statement cache properties). Для разъяснения этих свойств, пожалуйста обратитесь к документации по Apache commons-pool. Для использования Proxool, вы должны установить свойства hibernate.proxool.*.
Вот пример использования C3PO:
hibernate.connection.driver_class = org.postgresql.Driver hibernate.connection.url = jdbc:postgresql://localhost/mydatabase hibernate.connection.username = myuser hibernate.connection.password = secret hibernate.c3p0.minPoolSize=5 hibernate.c3p0.maxPoolSize=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statement=50 hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
Для использования внутри сервера приложений, Hibernate может получить соединения из зарегистрированного в JNDI javax.sql.Datasource. Установите следующие свойства:
Таблица 3.2. Свойства Источника Данных Hibernate (Hibernate Datasource Properties)
Имя свойства | Назначение |
---|---|
hibernate.connection.datasource | JNDI-имя источника данных |
hibernate.jndi.url | URL, указывающий на JNDI-провайдера (опционально) |
hibernate.jndi.class | JNDI-класс InitialContextFactory (опционально) |
hibernate.connection.username | пользователь базы данных (опционально) |
hibernate.connection.password | пароль пользователя базы данных (опционально) |
Вот пример использования источника данных предоставляемого через JNDI (JNDI datasource) сервером приложений:
hibernate.connection.datasource = java:/comp/env/jdbc/MyDB hibernate.transaction.factory_class = \ net.sf.hibernate.transaction.JTATransactionFactory hibernate.transaction.manager_lookup_class = \ net.sf.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect = \ net.sf.hibernate.dialect.PostgreSQLDialect
JDBC-соединения полученные из JNDI-источника данных, будут автоматически участвовать в транзакциях управляемых контейнером (container-managed transactions) сервера приложений.
Произвольные свойства JDBC-соединения могут быть заданы путем добавления "hibernate.connnection" к имени свойства. Например, вы можете указать charSet, используя следующее свойтсво hibernate.connnection.charSet.
Вы можете определить свой собственный, встраеваемый механизм (plugin) получения JDBC-соединений, реализуя интерфейс net.sf.hibernate.connection.ConnectionProvider. Установить желаемую реализацию net.sf.hibernate.connection.ConnectionProvider можно через свойство hibernate.connection.provider_class.
Сушествует большое количество других свойств, которые контролируют поведение Hibernate во время исполнения (runtime). Они необязательны и имеют разумные значения по умолчанию.
Свойства системного уровня могут быть установлены только через java -Dproperty=value или определены в hibernate.properties, но не с экземпляром класса Properties переданным в Configuration.
Таблица 3.3. Hibernate Configuration Properties
Имя свойства | Назначение |
---|---|
hibernate.dialect |
Имя класса Hibernate Dialect -- подключает определенную
платформозависимую функциональность.
например full.classname.of.Dialect |
hibernate.default_schema |
В сгенерированном SQL устанавливает имя схемы по умолчанию.
например SCHEMA_NAME |
hibernate.session_factory_name |
Экземпляр класса SessionFactory, будет автоматически привязан к этому
имени в JNDI после того, как экземпляр будет создан.
например jndi/composite/name |
hibernate.use_outer_join |
Делает возможной выборку данных с использование внешних соединений (outer join fetching).
Данный параметр нерекомендован к использованию (deprecated), используйте
max_fetch_depth.
например true | false |
hibernate.max_fetch_depth |
Устанавливает максимальную "глубину" дерева выборки данных с использованием
внешних соединений для неколлекционных ассоциаций (one-to-one, many-to-one).
0 отключает выборку данных по умолчанию с
использованием внешних соединений (по умолчанию неограничена).
Set a maximum "depth" for the outer join fetch tree
for single-ended associations (one-to-one, many-to-one).
A 0 disables default outer join fetching.
например рекомендованны значения между 0 и 3 |
hibernate.jdbc.fetch_size | Ненулевое значение определяет JDBC fetch size (вызов Statement.setFetchSize()). |
hibernate.jdbc.batch_size |
Не нулевое значение позволяет Hibernate использовать JDBC2 групповое обновление данных
(JDBC2 batch updates).
например рекомендованны значения между 5 и 30 |
hibernate.jdbc.use_scrollable_resultset |
Дает возможность Hibernate использовать JDBC2 scrollable resultsets. Это свойство
необходимо лишь в случае, использования предоставляемых пользователем
JDBC-соединений, иначе Hibernate использует метаданные соединения (connection metadata).
например true | false |
hibernate.jdbc.use_streams_for_binary |
Использовать потоки когда пишутся/читаются бинарные
или сериализуемые данные в/из JDBC. Это свойство системного уровня
(system-level property).
например true | false |
hibernate.jdbc.use_get_generated_keys |
Позволяет использовать JDBC3 вызов PreparedStatement.getGeneratedKeys()
для того, чтобы получать ключи сгенеренный базой данных (natively generated keys)
после произведенной вставки (SQL insert). Требует JDBC3+ драйвер и JRE1.4+.
Установите данное свойство в false, если ваш драйвер имеет проблемы с генераторами
идентификаторов предоставляемыми Hibernate. По умолчанию Hibernate пытается определить
возможности драйвера используя метаданные соединения.
например true|false |
hibernate.cglib.use_reflection_optimizer |
Позволяет использовать CGLIB вместо стандартного runtime reflection (свойство
системного уровня, по умолчанию, где это возможно, используется CGLIB).
Стандартный reflection может быть полезен при поиске неисправностей.
например true | false |
hibernate.jndi.<propertyName> | Передаёт свойство propertyName в JNDI InitialContextFactory. |
hibernate.connection.isolation |
Устанавливает уровень изоляции JDBC-транзакций (JDBC transaction isolation level).
Посмотрите на документацию к java.sql.Connection для
получения значимых значений, но обратите внимание, что не все базы данных
поддерживают все уровни изоляций.
например 1, 2, 4, 8 |
hibernate.connection.<propertyName> | Передает JDBC-свойство propertyName вызову DriverManager.getConnection(). |
hibernate.connection.provider_class |
Имя класса используемого провайдера соединений, реализующего интерфейс
ConnectionProvider.
например classname.of.ConnectionProvider |
hibernate.cache.provider_class |
Имя класса используемого кэш-провайдера, реализующего интерфейс
CacheProvider.
например classname.of.CacheProvider |
hibernate.cache.use_minimal_puts |
Оптимизировать операции кэша второго уровня (second-level cache),
минимизируя операции записи, ценой более частых считываний (полезно при использовании
кластерных кэшей).
например true|false |
hibernate.cache.use_query_cache |
Позволяет использовать кэш для запросов (query cache). Для каждого из запросов,
использование кэша должно быть установлено программно.
например true|false |
hibernate.cache.region_prefix |
Приставка используемая для имен регионов кэша второго уровня
(A prefix to use for second-level cache region names).
например prefix |
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,
требуется когда в JTA-окружении включен кэш уровня JVM
(JVM-level cache = second-level cache)
например classname.of.TransactionManagerLookup |
hibernate.query.substitutions |
Отображения/мэппинги из маркеров Hibernate запросов в SQL маркеры (например, маркеры могут
быть функциональными или литеральными именами (function or literal names)).
Мэппинг/отображение лексем (tokens) из запросов Hibernate в лексемы SQL
(например лексемой могут быть имя функции или буквенная константа).
например hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC |
hibernate.show_sql |
Логировать все SQL-выражения на консоль.
например true | false |
hibernate.hbm2ddl.auto |
Автоматически экспортировать DDL-схему в бузу данных,
после создания SessionFactory.
С установленным значением create-drop,
схема базы данных будет удалена, когда SessionFactory
будет закрыта явно (в ручную).
например update | create | create-drop |
Вы всегда должны устанавливать свойство hibernate.dialect в имя класса, который является подклассом net.sf.hibernate.dialect.Dialect для требуемой вам базы данных. Но это не является строгим требованием, если вы не собираетесь использовать следующие генераторы первичных ключей: native или sequence, и не используете пессимистичных блокировок (pessimistic locking), например используя вызовы: Session.lock() или Query.setLockMode(). Однако, если вы указали правильный диалект, Hibernate будет использовать разумные значения параметров, перечисленных выше, освобождая вас от необходимости указывать их вручную.
Таблица 3.4. Диалекты SQL, поддерживаемые Hibernate (hibernate.dialect)
Реляционная СУБД | Диалект |
---|---|
DB2 | net.sf.hibernate.dialect.DB2Dialect |
MySQL | net.sf.hibernate.dialect.MySQLDialect |
SAP DB | net.sf.hibernate.dialect.SAPDBDialect |
Oracle (любой версии) | net.sf.hibernate.dialect.OracleDialect |
Oracle 9 | net.sf.hibernate.dialect.Oracle9Dialect |
Sybase | net.sf.hibernate.dialect.SybaseDialect |
Sybase Anywhere | net.sf.hibernate.dialect.SybaseAnywhereDialect |
Progress | net.sf.hibernate.dialect.ProgressDialect |
Mckoi SQL | net.sf.hibernate.dialect.MckoiDialect |
Interbase | net.sf.hibernate.dialect.InterbaseDialect |
Pointbase | net.sf.hibernate.dialect.PointbaseDialect |
PostgreSQL | net.sf.hibernate.dialect.PostgreSQLDialect |
HypersonicSQL | net.sf.hibernate.dialect.HSQLDialect |
Microsoft SQL Server | net.sf.hibernate.dialect.SQLServerDialect |
Ingres | net.sf.hibernate.dialect.IngresDialect |
Informix | net.sf.hibernate.dialect.InformixDialect |
FrontBase | net.sf.hibernate.dialect.FrontbaseDialect |
Если ваша база данных поддерживает внешние соединения (outer joins) в стиле ANSI или Oracle, выборка данных с использованием внешних соединений (outer join fetching) может увеличить производительность вашего приложения, путем ограничения числа полных обходов дерева поиска (возможно, ценой увеличения нагружки на базу данных, т.к. часть работы перекладывается на нее). Выборка данных с использованием внешних соединений, позволяет выбирать данные для графа объектов, соединенных посредством many-to-one, one-to-many или one-to-one ассоциаций, используя всего один SQL SELECT запрос.
Загруженный граф объектов заканчивается "листьями". По умолчанию, в качестве "листьев" выступают "крайние" в ассоции объекты, коллекции, объекты с установленным "заместителем" -- прокси (proxy) или объекты с циклическими ссылками.
Для определенной ассоциации, выборка данных может быть разрешена или запрещена (а поведение по умолчанию изменено) установкой атрибута outer-join в XML-мэппинге (XML mapping).
Выборка данных с использованием внешних соединений, может быть отключена глобально, установкой свойства hibernate.max_fetch_depth в 0. Установка данного свойства в 1 или выше включает использование внешних соединений при выборке данных для всех one-to-one и many-to-one ассоциаций, у которых атрибут outer-join установлен в значение по умолчанию auto. Тем не мене, one-to-many ассоциации и коллекции, выбираются с использованием внешних соединений, только при явно установленном атрибуте outer-join в true. Данное поведение может быть изменено во время исполнения запросов Hibernate.
Изменение сконфигурированных внешних соединений может производиться через использование полных выборок данных (EAGER FETCH>), в HQL, используя LEFT JOIN FECH конструкцию, в Criteria API -- Criteria.setFetchMode().
Oracle ограничивает размер byte-массивов, которые могут быть переданы через их JDBC- драйвер. Если вы хотите использовать большие экземпляры типов binary или serializable, вам нужно включить свойство hibernate.jdbc.use_streams_for_binary. Это свойство уровня JVM.
Вы можете интегрировать кэш-систему уровня JVM, так же называемый кэш второго уровня (second-level cache) также вы можете реализовать кластерный кэш, реализуя интерфейс net.sf.hibernate.cache.CacheProvider. Вы можете использовать желаемую реализацию, установив свойство hibernate.cache.provider_class.
Если вы желаете использовать Hibernate Transaction API, вы должны указать класс фабрики (factory class) для экземпляров Transaction, установив свойство hibernate.transaction.factory_class. Hibernate Transaction API скрывает нижележащий механизм транзакций и позволяет коду Hibernate исполняться как в управляемом контейнером (container managed), так и в неуправляемом окружении.
Кэш первого кровня (first-level cache) -- это Hibernate Session.
Существует 2 стандартных (встроенных) выбора:
все вызовы делегируются вызовам JDBC-транзакций, используются транзакции базы данных (по умолчанию)
вызовы делегируются JTA (если на момент вызова, транзакция уже существует, Session выполняет свою работу в контексте этой транзакции, иначе стартуется новая транзакция).
Также вы можете определить свою собственную стратегию транзакций (например для службы транзакций CORBA).
Если, в JTA окружении, вы хотите использовать кэширование уровня JVM для изменяемых данных (mutable data), вы должны специфицировать стратегию получения менеджера транзакций JTA, TransactionManager, так как он не стандартизирован для J2EE контейнеров:
Таблица 3.5. Менеджеры транзакций JTA
Фабрика Транзакций (Transaction Factory) | Сервер Приложений |
---|---|
net.sf.hibernate.transaction.JBossTransactionManagerLookup | JBoss |
net.sf.hibernate.transaction.WeblogicTransactionManagerLookup | Weblogic |
net.sf.hibernate.transaction.WebSphereTransactionManagerLookup | WebSphere |
net.sf.hibernate.transaction.OrionTransactionManagerLookup | Orion |
net.sf.hibernate.transaction.ResinTransactionManagerLookup | Resin |
net.sf.hibernate.transaction.JOTMTransactionManagerLookup | JOTM |
net.sf.hibernate.transaction.JOnASTransactionManagerLookup | JOnAS |
net.sf.hibernate.transaction.JRun4TransactionManagerLookup | JRun4 |
Экземпляр класса SessionFactory, привязанный к JNDI, может упростить поиск фабрики и создание новых сессий (объекты класса Session).
Если вы хотите привязать экземпляр класса SessionFactory к JNDI-пространству имен, укажите имя (например, java:comp/env/hibernate/SessionFactory), используя свойство hibernate.session_factory_name. Если это свойство не указано, SessionFactory не будет привязан к JNDI. (Это особенно полезно в окружениях с реализацией JNDI только-на-чтение, например Tomcat.)
Для привязывания экземпляра класса SessionFactory к JNDI, Hibernate использует значения свойств hibernate.jndi.url, hibernate.jndi.class для инстанционирования инициализационного контекста (initial context). Если данные свойства не указаны, то будет использован InitialContext по умолчанию.
Если вы решили использовать JNDI, то EJB или какой-нибудь вспомогательный класс, могут получить SessionFactory используя поиск по JNDI (JNDI lookup).
Используя свойство hibernate.query.substitutions, вы можете определить новые лексемы (tokens) для запросов Hibernate. Например:
hibernate.query.substitutions true=1, false=0
приведет к тому что значения true и false, в SQL-запросе, будут заменены целочисленными литералами (integer literals).
hibernate.query.substitutions toLowercase=LOWER
позволит вам переименовать SQL-функцию LOWER.
Hibernate логирует различные события, используя библиотеку Apache commons-logging.
Библиотека commons-loggins перенаправляет логируемые события либо к Apache Log4j (если вы поместили log4j.jar в ваш classpath), либо к механизму логирования JDK1.4 (если вы используете JDK1.4 или выше). Вы можете загрузить библиотеку Log4j с сайта http://jakarta.apache.org. Для использования Log4j вы должны поместить файл сойств log4j.properties в ваш classpath, пример такого файла поставляется с Hibernate в каталоге src/.
Мы настоятельно рекомендуем вам ознакомиться с сообщениями логируемыми Hibernate. Было выполнено много работы, для чтобы сделать эти сообщения как можно более детальными, описательеными и удобными для чтения. Логирование является необходимым средством при поиске неисправностей. Так же не забудьте подключить логирование SQL-запросов, как это описано выше (hibernate.show_sql), это первый шаг который вы должны выполнить при поиске проблем с производительностью.
Интерфейс net.sf.hibernate.cfg.NamingStrategy позволяет вам указать "стандарт именований" ("naming standard") для объектов базы данных и элементов схемы.
Вы можете предоставить правила для именования идентификаторов базы данных на основе Java-идентификаторов. Эти правила будут использоваться при автоматической генерации схемы базы данных или при обработке заданных в файле мэппинга "логических" имен колонок и таблиц в "физические" имена. Эта особенность позволяет уменьшить многословность документов мэппинга, удаляет повторяющиеся "помехи" (repetitive noise), например в виде префиксов к именам таблиц TBL_ и делает файлы мэппинга более читабельными. Стратегия по умолчанию, используемая Hibernate, достаточно минимальная.
Вы можете указать различные стратегии вызвав метод Configuration.setNamingStrategy(), перед добавлением мэппингов:
SessionFactory sf = new Configuration() .setNamingStrategy(ImprovedNamingStrategy.INSTANCE) .addFile("Item.hbm.xml") .addFile("Bid.hbm.xml") .buildSessionFactory();
Стратегия именования net.sf.hibernate.cfg.ImprovedNamingStrategy, является встроенной стратегией и может быть использована в какчестве начальной точки для некоторых приложений.
Имеется альтернативный подход для конфигурирования Hibernate, это указать все настройки в файле названном hibernate.cfg.xml. Этот файл может быть использован для замещения файла hibernate.properties или если присутствуют оба файла, то для переопределения свойств указанных в hibernate.properties.
Ожидается, что конфигурационный XML-файл размещен в коревом каталоге вашего CLASSPATH. Вот пример файла hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> <hibernate-configuration> <!-- a SessionFactory instance listed as /jndi/name --> <session-factory name="java:comp/env/hibernate/SessionFactory"> <!-- properties --> <property name="connection.datasource">my/first/datasource</property> <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property> <property name="show_sql">false</property> <property name="use_outer_join">true</property> <property name="transaction.factory_class"> net.sf.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"/> </session-factory> </hibernate-configuration>
Теперь для конфигурирования Hibernate надо просто выполнить следующий код
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Вы можете выбрать другой конфигурационный XML-файл используя
SessionFactory sf = new Configuration() .configure("catdb.cfg.xml") .buildSessionFactory();