Hibernate.org Community Documentation

- Anterior
- Próxima

## Capítulo 3. Configuration

Devido ao fato do Hibernate ser projetado para operar em vários ambientes diferentes, há um grande número de parâmetros de configuração. Felizmente, a maioria possui valores padrão consideráveis e o Hibernate é distribuído com um arquivo `hibernate.properties` de exemplo no `etc/` que mostra várias opções. Apenas coloque o arquivo de exemplo no seu classpath e personalize-o.

## 3.1. Configuração programática

Uma instância de `org.hibernate.cfg.Configuration` representa um conjunto inteiro de mapeamentos de tipos Java de aplicação para um banco de dados SQL. O `org.hibernate.cfg.Configuration` é usado para construir uma `SessionFactory` imutável. Os mapeamentos são compilados a partir de diversos arquivos de mapeamento XML.

Você pode obter uma instância `org.hibernate.cfg.Configuration` intanciando-a diretamente e especificando os documentos de mapeamento XML. Se os arquivos de mapeamento estiverem no classpath, use `addResource()`. Por exemplo:

    Configuration cfg = new Configuration()

        .addResource("Item.hbm.xml")

        .addResource("Bid.hbm.xml");

Uma alternativa é especificar a classe mapeada e permitir que o Hibernate encontre o documento de mapeamento para você:

    Configuration cfg = new Configuration()

        .addClass(org.hibernate.auction.Item.class)

        .addClass(org.hibernate.auction.Bid.class);

O Hibernate procurará pelos arquivos de mapeamento chamados `/org/hibernate/auction/Item.hbm.xml` e `/org/hibernate/auction/Bid.hbm.xml` no classpath. Esta abordagem elimina qualquer nome de arquivo de difícil compreensão.

Uma `Configuration` também permite que você especifique propriedades de configuração específica. Por exemplo:

    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");

Esta não é a única forma de passar as propriedades de configuração para o Hibernate. As várias opções incluem:

1. Passar uma instância de `java.util.Properties` para `Configuration.setProperties()`.

2. Colocar `hibernate.properties` de arquivo nomeado no diretório raíz do classpath.

3. Determinar as propriedades do `System` usando `java -Dproperty=value`.

4. Incluir elementos `<property>` no `hibernate.cfg.xml` (discutido mais tarde).

Caso você deseje inicializar rapidamente o `hibernate.properties` é a abordagem mais rápida.

O `org.hibernate.cfg.Configuration` é previsto como um objeto de tempo de inicialização, a ser descartado quando um `SessionFactory` for criado.

## 3.2. Obtendo uma SessionFactory

Quando todos os mapeamentos forem analisados pelo `org.hibernate.cfg.Configuration`, a aplicação deve obter uma factory para as instâncias do `org.hibernate.Session`. O objetivo desta factory é ser compartilhado por todas as threads da aplicação:

    SessionFactory sessions = cfg.buildSessionFactory();

O Hibernate permite sua aplicação instanciar mais do que um `org.hibernate.SessionFactory`. Isto será útil se você estiver usando mais do que um banco de dados.

## 3.3. Conexões JDBC

Normalmente, você deseja que o `org.hibernate.SessionFactory` crie e faça um um pool de conexões JDBC para você. Se você seguir essa abordagem, a abertura de um `org.hibernate.Session` será tão simples quanto:

    Session session = sessions.openSession(); // open a new Session

Assim que você fizer algo que requeira o acesso ao banco de dados, uma conexão JDBC será obtida a partir do pool.

Para esse trabalho, precisaremos passar algumas propriedades da conexão JDBC para o Hibernate. Todos os nomes de propriedades Hibernate e semânticas são definidas na classe `org.hibernate.cfg.Environment`. Descreveremos agora as configurações mais importantes para a conexão JDBC.

O Hibernate obterá conexões (e efetuará o pool) usando `java.sql.DriverManager` se você determinar as seguintes propriedades:

Tabela 3.1. Propriedades JDBC Hibernate

Nome da Propriedade | Propósito
--- | ---
hibernate.connection.driver_class | JDBC driver class
hibernate.connection.url | JDBC URL
hibernate.connection.username | database user
hibernate.connection.password | database user password
hibernate.connection.pool_size | maximum number of pooled connections

No entanto, o algoritmo de pool de conexões do próprio Hibernate é um tanto rudimentar. A intenção dele é ajudar a iniciar e não para ser usado em um sistema de produção ou até para testar o desempenho. Você deve utilizar um pool de terceiros para conseguir um melhor desempenho e estabilidade. Apenas substitua a propriedade `hibernate.connection.pool_size` pela configuração específica do pool de conexões. Isto irá desligar o pool interno do Hibernate. Por exemplo, você pode gostar de usar C3P0.

O C3P0 é um pool conexão JDBC de código aberto distribuído junto com Hibernate no diretório `lib`. O Hibernate usará o próprio `org.hibernate.connection.C3P0ConnectionProvider` para o pool de conexão se você configurar a propriedade `hibernate.c3p0.*`. Se você gostar de usar Proxool, consulte o pacote `hibernate.properties` e o web site do Hibernate para mais informações.

Este é um exemplo de arquivo `hibernate.properties` para 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.PostgreSQLDialect

Para usar dentro de um servidor de aplicação, você deve configurar o Hibernate para obter conexões de um servidor de aplicação `javax.sql.Datasource` registrado no JNDI. Você precisará determinar pelo menos uma das seguintes propriedades:

Tabela 3.2. Propriedades do Datasource do Hibernate

Nome da Propriedade | Propósito
--- | ---
hibernate.connection.datasource | datasource JNDI name
hibernate.jndi.url | URL do fornecedor JNDI (opcional)
hibernate.jndi.class | classe de JNDI `InitialContextFactory` (opcional)
hibernate.connection.username | usuário de banco de dados (opcional)
hibernate.connection.password | senha de usuário de banco de dados (opcional)

Eis um exemplo de arquivo `hibernate.properties` para um servidor de aplicação fornecedor de fontes de dados 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.PostgreSQLDialect

Conexões JDBC obtidas de um datasource JNDI irão automaticamente participar das transações gerenciadas pelo recipiente no servidor de aplicação.

As propriedades de conexão arbitrárias podem ser acrescentandas ao "`hibernate.connnection`" ao nome da propriedade. Por exemplo, você deve especificar a propriedade de conexão `charSet` usando hibernate.connection.charSet.

Você pode definir sua própria estratégia de plugin para obter conexões JDBC implementando a interface `org.hibernate.connection.ConnectionProvider` e especificando sua implementação customizada através da propriedade `hibernate.connection.provider_class`.

## 3.4. Propriedades opcionais de configuração

Há um grande número de outras propriedades que controlam o comportamento do Hibernate em tempo de execução. Todos são opcionais e têm valores padrão lógicos.

## Atenção

Algumas destas propriedades são somente em nível de sistema.. As propriedades em nível de sistema podem ser determinadas somente via `java -Dproperty=value` ou `hibernate.properties`. Elas não podem ser configuradas por outras técnicas descritas acima.

Tabela 3.3. Propriedades de Configuração do Hibernate

Nome da Propriedade | Propósito
--- | ---
hibernate.dialect | O nome da classe de um Hibernate `org.hibernate.dialect.Dialect` que permite o Hibernate gerar SQL otimizado para um banco de dados relacional em particular. e.g. `full.classname.of.Dialect` Na maioria dos casos, o Hibernate irá atualmente estar apto a escolher a implementação `org.hibernate.dialect.Dialect` correta baseada no `JDBC metadata` retornado pelo JDBC driver.
hibernate.show_sql | Escreve todas as instruções SQL no console. Esta é uma alternativa para configurar a categoria de log `org.hibernate.SQL` to `debug`. e.g. `true` | `false`
hibernate.format_sql | Imprime o SQL formatado no log e recipiente. e.g. `true` | `false`
hibernate.default_schema | Qualifica no SQL gerado, os nome das tabelas desqualificadas com o esquema/espaço da tabela dado. e.g. `SCHEMA_NAME`
hibernate.default_catalog | Qualifica no SQL gerado, os nome das tabelas desqualificadas com catálogo dado. e.g. `CATALOG_NAME`
hibernate.session_factory_name | O `org.hibernate.SessionFactory` irá automaticamente se ligar a este nome no JNDI depois de ter sido criado. e.g. `jndi/composite/name`
hibernate.max_fetch_depth | Estabelece a "profundidade" máxima para árvore de busca de união externa para associações finais únicas (um para um, muitos para um). Um `0` desativa por padrão a busca de união externa. eg. valores recomendados entre`0` e `3`
hibernate.default_batch_fetch_size | Determina um tamanho padrão para busca de associações em lotes do Hibernate. eg. valores recomendados `4`, `8`, `16`
hibernate.default_entity_mode | Determina um modo padrão para representação de entidade para todas as sessões abertas desta `SessionFactory` `dynamic-map`, `dom4j`, `pojo`
hibernate.order_updates | Força o Hibernate a ordenar os updates SQL pelo valor da chave primária dos ítens a serem atualizados. Isto resultará em menos deadlocks nas transações em sistemas altamente concorrente. e.g. `true` | `false`
hibernate.generate_statistics | Se habilitado, o Hibernate coletará estatísticas úteis para o ajuste do desempenho. e.g. `true` | `false`
hibernate.use_identifier_rollback | Se habilitado, propriedades identificadoras geradas serão zeradas para os valores padrão quando os objetos forem apagados. e.g. `true` | `false`
hibernate.use_sql_comments | Se ligado, o Hibernate irá gerar comentários dentro do SQL, para facilitar a depuração, o valor padrão é `false` e.g. `true` | `false`
hibernate.id.new_generator_mappings | Setting is relevant when using `@GeneratedValue`. It indicates whether or not the new `IdentifierGenerator` implementations are used for `javax.persistence.GenerationType.AUTO`, `javax.persistence.GenerationType.TABLE` and `javax.persistence.GenerationType.SEQUENCE`. Default to `false` to keep backward compatibility. e.g. `true` | `false`

## Nota

We recommend all new projects which make use of to use `@GeneratedValue` to also set `hibernate.id.new_generator_mappings=true` as the new generators are more efficient and closer to the JPA 2 specification semantic. However they are not backward compatible with existing databases (if a sequence or a table is used for id generation).

Tabela 3.4. JDBC Hibernate e Propriedades de Conexão

Nome da Propriedade | Propósito
--- | ---
hibernate.jdbc.fetch_size | Um valor maior que zero determina o tamanho da buscado JDBC (chamadas `Statement.setFetchSize()`).
hibernate.jdbc.batch_size | Um valor maior que zero habilita o uso das atualizações em lotes JDBC2 pelo Hibernate. ex. valores recomentados entre `5` e `30`
hibernate.jdbc.batch_versioned_data | Set this property to `true` if your JDBC driver returns correct row counts from `executeBatch()`. It is usually safe to turn this option on. Hibernate will then use batched DML for automatically versioned data. Defaults to `false`. e.g. `true` | `false`
hibernate.jdbc.factory_class | Escolher um `org.hibernate.jdbc.Batcher`. Muitas aplicações não irão precisar desta propriedade de configuração. exemplo `classname.of.BatcherFactory`
hibernate.jdbc.use_scrollable_resultset | Habilita o uso dos resultados de ajustes roláveis do JDBC2 pelo Hibernate. Essa propriedade somente é necessária quando se usa Conexões JDBC providas pelo usuário. Do contrário, o Hibernate os os metadados da conexão. e.g. `true` | `false`
hibernate.jdbc.use_streams_for_binary | Utilize fluxos para escrever/ler tipos `binary` ou tipos `serializable` para/do JDBC. *system-level property* e.g. `true` | `false`
hibernate.jdbc.use_get_generated_keys | Possibilita o uso do `PreparedStatement.getGeneratedKeys()` JDBC3 para recuperar chaves geradas de forma nativa depois da inserção. Requer driver JDBC3+ e JRE1.4+, ajuste para falso se seu driver tiver problemas com gerador de indentificadores Hibernate. Por padrão, tente determinar o driver capaz de usar metadados da conexão. exemplo `true|false`
hibernate.connection.provider_class | O nome da classe de um `org.hibernate.connection.ConnectionProvider`, do qual proverá conexões JDBC para o Hibernate. exemplo `classname.of.ConnectionProvider`
hibernate.connection.isolation | Determina o nível de isolamento de uma transação JDBC. Verifique `java.sql.Connection` para valores significativos mas note que a maior parte dos bancos de dados não suportam todos os isolamentos que não são padrões. exemplo `1, 2, 4, 8`
hibernate.connection.autocommit | Habilita o auto-commit para conexões no pool JDBC (não recomendado). e.g. `true` | `false`
hibernate.connection.release_mode | Especifica quando o Hibernate deve liberar conexões JDBC. Por padrão, uma conexão JDBC é retida até a sessão estar explicitamente fechada ou desconectada. Para uma fonte de dados JTA do servidor de aplicação, você deve usar `after_statement` para forçar a liberação da conexões depois de todas as chamadas JDBC. Para uma conexão não-JTA, freqüentemente faz sentido liberar a conexão ao fim de cada transação, usando `after_transaction`. O `auto` escolherá `after_statement` para as estratégias de transaçãoes JTA e CMT e `after_transaction` para as estratégias de transação JDBC. exemplo `auto` (padrão) | `on_close` | `after_transaction` | `after_statement` This setting only affects `Session`s returned from `SessionFactory.openSession`. For `Session`s obtained through `SessionFactory.getCurrentSession`, the `CurrentSessionContext` implementation configured for use controls the connection release mode for those `Session`s. See Seção 2.3, “Sessões Contextuais”
hibernate.connection.<propertyName> | Passar a propriedade JDBC <propertyName> para `DriverManager.getConnection()`.
hibernate.jndi.<propertyName> | Passar a propriedade <propertyName> para o JNDI `InitialContextFactory`.

Tabela 3.5. Propriedades de Cachê do Hibernate

Nome da Propriedade | Propósito
--- | ---
`hibernate.cache.provider_class` | O nome da classe de um `CacheProvider` personalizado. exemplo `classname.of.CacheProvider`
`hibernate.cache.use_minimal_puts` | Otimizar operação de cachê de segundo nível para minimizar escritas, ao custo de leituras mais freqüentes. Esta configuração é mais útil para cachês em cluster e, no Hibernate3, é habilitado por padrão para implementações de cache em cluster. exemplo `true|false`
`hibernate.cache.use_query_cache` | Habilita a cache de consultas. Mesmo assim, consultas individuais ainda têm que ser habilitadas para o cache. exemplo `true|false`
`hibernate.cache.use_second_level_cache` | Pode ser utilizado para desabilitar completamente o cache de segundo nível, o qual é habilitado por padrão para as classes que especificam um mapeamento `<cache>`. exemplo `true|false`
`hibernate.cache.query_cache_factory` | O nome de classe de uma interface personalizada `QueryCache`, padroniza para o `StandardQueryCache` criado automaticamente. exemplo `classname.of.QueryCache`
`hibernate.cache.region_prefix` | Um prefixo para usar em nomes regionais de cachê de segundo nível exemplo `prefix`
`hibernate.cache.use_structured_entries` | Força o Hibernate a armazenar dados no cachê de segundo nível em um formato mais humanamente amigável. exemplo `true|false`
`hibernate.cache.default_cache_concurrency_strategy` | Setting used to give the name of the default `org.hibernate.annotations.CacheConcurrencyStrategy` to use when either `@Cacheable` or `@Cache` is used. `@Cache(strategy="..")` is used to override this default.

Tabela 3.6. Propriedades de Transação do Hibernate

Nome da Propriedade | Propósito
--- | ---
`hibernate.transaction.factory_class` | O nome da classe de uma `TransactionFactory` para usar com API do Hibernate `Transaction` ( por padrão`JDBCTransactionFactory` ). exemplo `classname.of.TransactionFactory`
`jta.UserTransaction` | Um nome JNDI usado pelo `JTATransactionFactory`para obter uma `UserTransaction` JTA a partir do servidor de aplicação. e.g. `jndi/composite/name`
`hibernate.transaction.manager_lookup_class` | O nome da classe de um `TransactionManagerLookup`. Ele é requerido quando o caching a nível JVM estiver habilitado ou quando estivermos usando um gerador hilo em um ambiente JTA. exemplo `classname.of.TransactionManagerLookup`
`hibernate.transaction.flush_before_completion` | If enabled, the session will be automatically flushed during the before completion phase of the transaction. Built-in and automatic session context management is preferred, see Seção 2.3, “Sessões Contextuais”. e.g. `true` | `false`
`hibernate.transaction.auto_close_session` | If enabled, the session will be automatically closed during the after completion phase of the transaction. Built-in and automatic session context management is preferred, see Seção 2.3, “Sessões Contextuais”. e.g. `true` | `false`

Tabela 3.7. Propriedades Variadas

Nome da Propriedade | Propósito
--- | ---
`hibernate.current_session_context_class` | Supply a custom strategy for the scoping of the "current" `Session`. See Seção 2.3, “Sessões Contextuais” for more information about the built-in strategies. exemplo `jta` | `thread` | `managed` | `custom.Class`
`hibernate.query.factory_class` | Escolha a implementação de análise HQL. exemplo `org.hibernate.hql.ast. ASTQueryTranslatorFactory` ou `org.hibernate.hql.classic. ClassicQueryTranslatorFactory`
`hibernate.query.substitutions` | Mapeamento a partir de símbolos em consultas do Hibernate para para símbolos SQL (símbolos devem ser por exemplo, funções ou nome literais). exemplo `hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC`
`hibernate.hbm2ddl.auto` | Automaticamente valida ou exporta DDL esquema para o banco de dados quando o `SessionFactory` é criado. Com `create-drop`, o esquema do banco de dados será excluido quando a `SessionFactory` for fechada explicitamente. exemplo `validate` | `update` | `create` | `create-drop`
`hibernate.hbm2ddl.import_files` | Comma-separated names of the optional files containing SQL DML statements executed during the `SessionFactory` creation. This is useful for testing or demoing: by adding INSERT statements for example you can populate your database with a minimal set of data when it is deployed. File order matters, the statements of a give file are executed before the statements of the following files. These statements are only executed if the schema is created ie if `hibernate.hbm2ddl.auto` is set to `create` or `create-drop`. e.g. `/humans.sql,/dogs.sql`
`hibernate.bytecode.use_reflection_optimizer` | Enables the use of bytecode manipulation instead of runtime reflection. This is a System-level property and cannot be set in `hibernate.cfg.xml`. Reflection can sometimes be useful when troubleshooting. Hibernate always requires either CGLIB or javassist even if you turn off the optimizer. e.g. `true` | `false`
`hibernate.bytecode.provider` | Both javassist or cglib can be used as byte manipulation engines; the default is `javassist`. e.g. `javassist` | `cglib`

### 3.4.1. Dialetos SQL

Você deve sempre determinar a propriedade `hibernate.dialect` para a subclasse de `org.hibernate.dialect.Dialect` correta de seu banco de dados. Se você especificar um dialeto, o Hibernate usará padrões lógicos para qualquer um das outras propriedades listadas abaixo, reduzindo o esforço de especificá-los manualmente.

Tabela 3.8. Dialetos SQL do Hibernate (`hibernate.dialect`)

RDBMS | Dialeto
--- | ---
DB2 | `org.hibernate.dialect.DB2Dialect`
DB2 AS/400 | `org.hibernate.dialect.DB2400Dialect`
DB2 OS390 | `org.hibernate.dialect.DB2390Dialect`
PostgreSQL | `org.hibernate.dialect.PostgreSQLDialect`
MySQL5 | `org.hibernate.dialect.MySQL5Dialect`
MySQL5 with InnoDB | `org.hibernate.dialect.MySQL5InnoDBDialect`
Meu SQL com MeuISAM | `org.hibernate.dialect.MySQLMyISAMDialect`
Oracle (qualquer versão) | `org.hibernate.dialect.OracleDialect`
Oracle 9i | `org.hibernate.dialect.Oracle9iDialect`
Oracle 10g | `org.hibernate.dialect.Oracle10gDialect`
Oracle 11g | `org.hibernate.dialect.Oracle10gDialect`
Sybase | `org.hibernate.dialect.SybaseASE15Dialect`
Sybase Qualquer lugar | `org.hibernate.dialect.SybaseAnywhereDialect`
Microsoft SQL Server 2000 | `org.hibernate.dialect.SQLServerDialect`
Microsoft SQL Server 2005 | `org.hibernate.dialect.SQLServer2005Dialect`
Microsoft SQL Server 2008 | `org.hibernate.dialect.SQLServer2008Dialect`
SAP DB | `org.hibernate.dialect.SAPDBDialect`
Informix | `org.hibernate.dialect.InformixDialect`
HypersonicSQL | `org.hibernate.dialect.HSQLDialect`
H2 Database | `org.hibernate.dialect.H2Dialect`
Ingres | `org.hibernate.dialect.IngresDialect`
Progresso | `org.hibernate.dialect.ProgressDialect`
Mckoi SQL | `org.hibernate.dialect.MckoiDialect`
Interbase | `org.hibernate.dialect.InterbaseDialect`
Base Ponto | `org.hibernate.dialect.PointbaseDialect`
Base Frontal | `org.hibernate.dialect.FrontbaseDialect`
Firebird | `org.hibernate.dialect.FirebirdDialect`

### 3.4.2. Busca por união externa (Outer Join Fetching)

Se seu banco de dados suporta união externa no estilo ANSI, Oracle ou Sybase, a outer join fetching freqüentemente aumentará o desempenho limitando o número de chamadas (round trips) para e a partir do banco de dados. No entanto, isto ao custo de possivelmente mais trabalho desempenhado pelo próprio banco de dados. A busca por união externa (outer join fetching) permite um gráfico completo de objetos conectados por associações muitos-para-um, um-para-muitos, muitos-para-muitos e um-para-um para serem recuperadas em uma simples instrução SQL `SELECT`.

A busca por união externa pode ser desabilitada globalmente configurando a propriedade `hibernate.max_fetch_depth` para `0`. Um valor `1` ou maior habilita a busca por união externa para associações um-para-um e muitos-para-um, cujos quais têm sido mapeados com `fetch="join"`.

See Seção 21.1, “Estratégias de Busca ” for more information.

### 3.4.3. Fluxos Binários (Binary Streams)

O Oracle limita o tamanho de matrizes de `byte` que podem ser passadas para/do driver JDBC. Se você desejar usar grandes instâncias de tipos `binary` ou `serializable`, você deve habilitar `hibernate.jdbc.use_streams_for_binary`. Essa é uma configuração que só pode ser feita em nível de sistema.

### 3.4.4. Cachê de segundo nível e consulta

The properties prefixed by `hibernate.cache` allow you to use a process or cluster scoped second-level cache system with Hibernate. See the Seção 21.2, “O Cachê de Segundo Nível” for more information.

### 3.4.5. Substituição na Linguagem de Consulta

Você pode definir novos símbolos de consulta Hibernate usando `hibernate.query.substitutions`. Por exemplo:

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

Isto faria com que os símbolos `true` e `false` passasem a ser traduzidos para literais inteiros no SQL gerado.

    hibernate.query.substitutions toLowercase=LOWER

Isto permitirá que você renomeie a função `LOWER` no SQL.

### 3.4.6. Estatísticas do Hibernate

Se você habilitar `hibernate.generate_statistics`, o Hibernate exibirá um número de métricas bastante útil ao ajustar um sistema via `SessionFactory.getStatistics()`. O Hibernate pode até ser configurado para exibir essas estatísticas via JMX. Leia o Javadoc da interface `org.hibernate.stats` para mais informações.

## 3.5. Logging

O Hibernate utiliza o Simple Logging Facade for Java (SLF4J) com o objetivo de registrar os diversos eventos de sistema. O SLF4J pode direcionar a sua saída de logging a diversos frameworks de logging (NOP, Simple, log4j version 1.2, JDK 1.4 logging, JCL ou logback) dependendo de sua escolha de vinculação. Com o objetivo de determinar o seu logging, você precisará do `slf4j-api.jar` em seu classpatch juntamente com o arquivo jar para a sua vinculação preferida - `slf4j-log4j12.jar` no caso do Log4J. Consulte o SLF4J documentation para maiores detalhes. Para usar o Log4j você precisará também colocar um arquivo `log4j.properties` em seu classpath. Um exemplo do arquivo de propriedades está distribuído com o Hibernate no diretório `src/`.

Nós recomendamos que você se familiarize-se com mensagens de log do Hibernate. Tem sido um árduo trabalho fazer o log Hibernate tão detalhado quanto possível, sem fazê-lo ilegível. É um dispositivo de controle de erros essencial. As categorias de log mais interessantes são as seguintes:

Tabela 3.9. Categorias de Log do Hibernate

Categoria | Função
--- | ---
`org.hibernate.SQL` | Registra todas as instruções SQL DML a medida que elas são executadas
`org.hibernate.type` | Registra todos os parâmetros JDBC
`org.hibernate.tool.hbm2ddl` | Registra todas as instruções SQL DDL a medida que elas são executadas
`org.hibernate.pretty` | Registra o estado de todas as entidades (máximo 20 entidades) associadas à sessão no momento da liberação (flush).
`org.hibernate.cache` | Registra todas as atividades de cachê de segundo nível
`org.hibernate.transaction` | Registra atividades relacionada à transação
`org.hibernate.jdbc` | Registra todas as requisições de recursos JDBC
`org.hibernate.hql.ast.AST` | Registra instruções SQL e HQL durante a análise da consultas
`org.hibernate.secure` | Registra todas as requisições de autorização JAAS
`org.hibernate` | Registra tudo. Apesar de ter muita informação, é muito útil para o problema de inicialização.

Ao desenvolver aplicações com Hibernate, você deve quase sempre trabalhar com o depurador `debug` habilitado para a categoria `org.hibernate.SQL`, ou, alternativamente, com a propriedade `hibernate.show_sql` habilitada.

## 3.6. Implementando um `NamingStrategy`

A interface `org.hibernate.cfg.NamingStrategy` permite que você especifique um "padrão de nomeação" para objetos do banco de dados e elementos de esquema.

Você deve criar regras para a geração automaticamente de identificadores do banco de dados a partir de identificadores Java ou para processar colunas "lógicas" e nomes de tabelas dado o arquivo de mapeamento para nomes "físicos" de tabelas e colunas. Este recurso ajuda a reduzir a verbosidade do documento de mapeamento, eliminando interferências repetitivas (`TBL_` prefixos, por exemplo). A estratégia padrão usada pelo Hibernate é bastante mínima.

Você pode especificar uma estratégia diferente ao chamar `Configuration.setNamingStrategy()` antes de adicionar os mapeamentos:

    SessionFactory sf = new Configuration()

        .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)

        .addFile("Item.hbm.xml")

        .addFile("Bid.hbm.xml")

        .buildSessionFactory();

`org.hibernate.cfg.ImprovedNamingStrategy` é uma estratégia interna que pode ser um ponto inicial útil para algumas aplicações.

## 3.7. Implementing a PersisterClassProvider

You can configure the persister implementation used to persist your entities and collections:

- by default, Hibernate uses persisters that make sense in a relational model and follow Java Persistence's specification

- you can define a `PersisterClassProvider` implementation that provides the persister class used of a given entity or collection

- finally, you can override them on a per entity and collection basis in the mapping using `@Persister` or its XML equivalent

The latter in the list the higher in priority.

You can pass the `PersisterClassProvider` instance to the `Configuration` object.

    SessionFactory sf = new Configuration()

        .setPersisterClassProvider(customPersisterClassProvider)

        .addAnnotatedClass(Order.class)

        .buildSessionFactory();

The persister class provider methods, when returning a non null persister class, override the default Hibernate persisters. The entity name or the collection role are passed to the methods. It is a nice way to centralize the overriding logic of the persisters instead of spreading them on each entity or collection mapping.

## 3.8. Arquivo de configuração XML

Uma maneira alternativa de configuração é especificar uma configuração completa em um arquivo chamado `hibernate.cfg.xml`. Este arquivo pode ser usado como um substituto para o arquivo `hibernate.properties` ou, se ambos estiverem presentes, para substituir propriedades.

O arquivo XML de configuração deve ser encontrado na raíz do seu `CLASSPATH`. Veja um exemplo:

    <?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>

Como você pode ver, a vantagem deste enfoque é a externalização dos nomes dos arquivos de mapeamento para configuração. O `hibernate.cfg.xml` também é mais conveniente caso você tenha que ajustar o cache do Hibernate. Note que a escolha é sua em usar `hibernate.properties` ou `hibernate.cfg.xml`, ambos são equivalentes, exceto os acima mencionados de usar a sintaxe de XML.

Com a configuração do XML, iniciar o Hibernate é então tão simples quanto:

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

Você poderá escolher um arquivo de configuração XML diferente, utilizando:

    SessionFactory sf = new Configuration()

        .configure("catdb.cfg.xml")

        .buildSessionFactory();

## 3.9. Java EE Application Server integration

O Hibernate tem os seguintes pontos da integração para a infraestrutura de J2EE:

- DataSources gerenciados pelo container: O Hibernate pode usar conexões JDBC gerenciadas pelo Container e fornecidas pela JNDI. Geralmente, um `TransactionManager` compatível com JTA e um `ResourceManager` cuidam do gerenciamento da transação (CMT), especialmente em transações distribuídas, manipuladas através de vários DataSources. Naturalmente, você também pode demarcar os limites das transações programaticamente (BMT) ou você poderia querer usar a API opcional do Hibernate `Transaction` para esta manter seu código portável.

- Vinculação (binding) automática à JNDI: O Hibernate pode associar sua `SessionFactory` a JNDI depois de iniciado.

- Vinculação (binding) da Sessão na JTA: A `Session` do Hibernate pode automaticamente ser ligada ao escopo da transações JTA. Simplesmente localizando a `SessionFactory` da JNDI e obtendo a `Session` corrente. Deixe o Hibernate cuidar da liberação e encerramento da `Session` quando as transações JTA terminarem. A Demarcação de transação pode ser declarativa (CMT) ou programática (BMT/Transação do usuário).

- JMX deployment: Se você usa um JMX servidor de aplicações capaz (ex. Jboss AS), você pode fazer a instalação do Hibernate como um MBean controlado. Isto evita ter que iniciar uma linha de código para construir sua `SessionFactory` de uma `Configuration`. O container iniciará seu `HibernateService`, e também cuidará das dependências de serviços (DataSources, têm que estar disponíveis antes do Hibernate iniciar, etc.).

Dependendo do seu ambiente, você pode ter que ajustar a opção de configuração `hibernate.connection.aggressive_release` para verdadeiro ( true ), se seu servidor de aplicações lançar exeções "retenção de conexão".

### 3.9.1. Configuração de estratégia de transação

A API Hibernate `Session` é independente de qualquer sistema de demarcação de transação em sua arquitetura. Se você deixar o Hibernate usar a JDBC diretamente, através de um pool de conexões, você pode inicializar e encerrar suas transações chamando a API JDBC. Se você rodar em um servidor de aplicações J2EE, você poderá usar transações controladas por beans e chamar a API JTA e `UserTransaction` quando necessário.

Para manter seu código portável entre estes dois (e outros) ambientes, recomendamos a API Hibernate `Transaction`, que envolve e esconde o sistema subjacente. Você tem que especificar uma classe construtora para instâncias `Transaction` ajustando a propriedade de configuração do `hibernate.transaction.factory_class`.

Existem três escolhas, ou internas, padrões:

`org.hibernate.transaction.JDBCTransactionFactory`

  delega as transações (JDBC) para bases de dados (Padrão)

`org.hibernate.transaction.JTATransactionFactory`

  delega para uma transação à um container gerenciado se uma transação existente estiver de acordo neste contexto (ex: método bean de sessão EJB). No entanto, uma nova transação será iniciada e serão usadas transações controladas por um bean.

`org.hibernate.transaction.CMTTransactionFactory`

  delega para um container gerenciador de transações JTA

Você também pode definir suas próprias estratégias de transação (para um serviço de transação CORBA, por exemplo).

Algumas características no Hibernate (ex., o cache de segundo nível, sessões contextuais com JTA, etc.) requerem acesso a JTA `TransactionManager` em um ambiente controlado. Em um servidor de aplicação você tem que especificar como o Hibernate pode obter uma referência para a `TransactionManager`, pois o J2EE não padroniza um mecanismo simples:

Tabela 3.10. Gerenciadores de transações JTA

Factory de Transação | Servidor de Aplicação
--- | ---
`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 used standalone (ie. outside JBoss AS and a JNDI environment generally). Known to work for `org.jboss.jbossts:jbossjta:4.11.0.Final`

### 3.9.2. `SessionFactory` vinculada à JNDI

Uma `SessionFactory` de Hibernate vinculada à JNDI pode simplificar a localização da fábrica e a criação de novas `Session`s. Observe que isto não está relacionado a um `Datasource` ligado a JNDI, simplesmente ambos usam o mesmo registro.

Se você desejar ter uma `SessionFactory` limitada a um nome de espaço de JNDI, especifique um nome (ex.: `java:hibernate/SessionFactory`) usando a propriedade `hibernate.session_factory_name`. Se esta propriedade for omitida, a `SessionFactory` não será limitada ao JNDI. Isto é muito útil em ambientes com uma implementação padrão JNDI de somente leitura (ex.: Tomcat).

Ao vincular a `SessionFactory` ao JNDI, o Hibernate irá utilizar os valores de `hibernate.jndi.url`, `hibernate.jndi.class` para instanciar um contexto inicial. Se eles não forem especificados, será usado o padrão `InitialContext`.

O Hibernate colocará automaticamente a `SessionFactory` no JNDI depois que você chamar a `cfg.buildSessionFactory()`. Isto significa que você terá esta chamada em pelo menos algum código de inicialização (ou classe de utilidade) em seu aplicativo, a não ser que você use a implementação JMX com o `HibernateService` (discutido mais tarde).

Se você usar um JNDI `SessionFactory`, o EJB ou qualquer outra classe obterá a `SessionFactory` utilizando um localizador JNDI.

It is recommended that you bind the `SessionFactory` to JNDI in a managed environment and use a `static` singleton otherwise. To shield your application code from these details, we also recommend to hide the actual lookup code for a `SessionFactory` in a helper class, such as `HibernateUtil.getSessionFactory()`. Note that such a class is also a convenient way to startup Hibernate—see chapter 1.

### 3.9.3. Gerenciamento de contexto de Sessão atual com JTA

The easiest way to handle `Sessions` and transactions is Hibernate's automatic "current" `Session` management. For a discussion of contextual sessions see Seção 2.3, “Sessões Contextuais”. Using the `"jta"` session context, if there is no Hibernate `Session` associated with the current JTA transaction, one will be started and associated with that JTA transaction the first time you call `sessionFactory.getCurrentSession()`. The `Session`s retrieved via `getCurrentSession()` in the `"jta"` context are set to automatically flush before the transaction completes, close after the transaction completes, and aggressively release JDBC connections after each statement. This allows the `Session`s to be managed by the life cycle of the JTA transaction to which it is associated, keeping user code clean of such management concerns. Your code can either use JTA programmatically through `UserTransaction`, or (recommended for portable code) use the Hibernate `Transaction` API to set transaction boundaries. If you run in an EJB container, declarative transaction demarcation with CMT is preferred.

### 3.9.4. implementação JMX

A linha `cfg.buildSessionFactory()` ainda precisa ser executada em algum local para conseguir uma `SessionFactory` em JNDI. Você pode escolher fazer isto em um bloqueio de inicializador `static`, como aquele em `HibernateUtil`, ou implementar o Hibernate como serviço gerenciado.

O Hibernate é distribuído com o `org.hibernate.jmx.HibernateService` para implementação em um servidor de aplicativo com capacidades JMX, tal como o JBoss AS. A implementação atual e configuração é comercial. Segue aqui um exemplo do `jboss-service.xml` para o JBoss 4.0.x:

    <?xml version="1.0"?>

    <server>

    <mbean code="org.hibernate.jmx.HibernateService"

        name="jboss.jca:service=HibernateFactory,name=HibernateFactory">

        <!-- Required services -->

        <depends>jboss.jca:service=RARDeployer</depends>

        <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>

        <!-- Bind the Hibernate service to JNDI -->

        <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>

        <!-- Datasource settings -->

        <attribute name="Datasource">java:HsqlDS</attribute>

        <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>

        <!-- Transaction integration -->

        <attribute name="TransactionStrategy">

            org.hibernate.transaction.JTATransactionFactory</attribute>

        <attribute name="TransactionManagerLookupStrategy">

            org.hibernate.transaction.JBossTransactionManagerLookup</attribute>

        <attribute name="FlushBeforeCompletionEnabled">true</attribute>

        <attribute name="AutoCloseSessionEnabled">true</attribute>

        <!-- Fetching options -->

        <attribute name="MaximumFetchDepth">5</attribute>

        <!-- Second-level caching -->

        <attribute name="SecondLevelCacheEnabled">true</attribute>

        <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>

        <attribute name="QueryCacheEnabled">true</attribute>

        <!-- Logging -->

        <attribute name="ShowSqlEnabled">true</attribute>

        <!-- Mapping files -->

        <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>

    </mbean>

    </server>

Este arquivo é implementado em um diretório chamado `META-INF` e envolto em um arquivo JAR com a extensão `.sar` (arquivo de serviço). Você também pode precisar envolver o Hibernate, suas bibliotecas de terceiros solicitadas, suas classes persistentes compiladas, assim como seus arquivos de mapeamento no mesmo arquivo. Seus beans de empresa (geralmente beans de sessão) podem ser mantidos em seus próprios arquivos JAR, mas você poderá incluir estes arquivos EJB JAR no arquivo de serviço principal para conseguir uma única unidade de (hot)-deployable. Consulte a documentação do JBoss AS para maiores informações sobre o serviço JMX e implementação EJB.

Copyright © 2004 Red Hat, Inc.

- AnteriorCapítulo 2. Arquitetura
- Acima
- Principal
- PróximaCapítulo 4. Classes Persistentes