Remove ^M characters, match with latest English XML

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@14136 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
xhuang 2007-10-26 00:48:48 +00:00
parent c7bc162118
commit f14b750f88
24 changed files with 10951 additions and 10736 deletions

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="associations">
<chapter id="associations">
<title>Mapeamento de Associações</title>

View File

@ -1,360 +1,364 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="batch">
<title>Processamento de lotes</title>
<para>
Uma alternativa para inserir 100.000 linhas no banco de dados usando o Hibernate
pode ser a seguinte:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();]]></programlisting>
<para>
Isto irá falhar em algum lugar próximo a linha 50.000, lançando uma
<literal>OutOfMemoryException</literal>. Isso ocorre devido ao fato do Hibernate
fazer cache de todas as instâncias de <literal>Customer</literal> inseridas num
cachê em nível de sessão.
</para>
<para>
Neste capítulo veremos como contornar esse problema. Entretanto, se você vai realizar
processamento de lotes, é muito importante que você habilite o uso de lotes JDBC, se
você pretende obter um desempenho razoável. Defina o tamanho do lote JDBC em um
valor razoável (algo entre 10-50):
</para>
<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
<para>
Você também pode querer rodar esse tipo de processamento de lotes com o cache
secundário completamente desabilitado:
</para>
<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
<para>
Mas isto não é absolutamente necessário, desde que nós possamos ajustar o
<literal>CacheMode</literal> para desabilitar a interação com o cache secundário.
</para>
<sect1 id="batch-inserts">
<title>Inserção de lotes</title>
<para>
Quando você estiver inserindo novos objetos persistentes, vocês deve executar
os métodos <literal>flush()</literal> e <literal>clear()</literal> regularmente
na sessão, para controlar o tamanho do cache primário.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();]]></programlisting>
</sect1>
<sect1 id="batch-update" >
<title>Batch updates</title>
<para>
Para recuperar e atualizar informações a mesma idéia é válida. Adicionalmente,
pode precisar usar o <literal>scroll()</literal> para usar recursos no lado
do servidor em queries que retornam muita informação.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
if ( ++count % 20 == 0 ) {
//flush a batch of updates and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();]]></programlisting>
</sect1>
<sect1 id="batch-statelesssession">
<title>A interface StatelessSession</title>
<para>
Alternativamente, o Hibernate provê uma API orientada à comandos, usada para
transmitir um fluxo de dados de e para o banco de dados na forma de objetos soltos.
Uma <literal>StatelessSession</literal> não tem um contexto persistente associado e
não fornece muito das semânticas de alto nível para controle do ciclo de vida.
Em especial, uma StatelessSession não implemente o cache primário e nem interage
com o cache secundário ou query cache. Ele não implementa salvamento transacional
automatico ou checagem automática de mudanças. Operação realizadas usando uma
StatelessSession não fazem nenhum tipo de cascade com as instancias associadas.
As coleções são ignoradas por uma StatelessSession. Operações realizadas com um
StatelessSession ignoram a arquitetura de eventos e os interceptadores.
StatelessSession são vulneráveis aos efeitos do aliasing dos dados, devido a
falta do cache primário. Uma StatelessSession é uma abstração de baixo nível,
muito mais próxima do JDBC.
</para>
<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
session.update(customer);
}
tx.commit();
session.close();]]></programlisting>
<para>
Veja neste exempo, as instancias de <literal>Customer</literal> retornadas pela query
são imediatamente desvinculadas. Elas nunca serão assossiadas à um contexto persistente.
</para>
<para>
As operações <literal>insert(), update()</literal> e <literal>delete()</literal>
definidos pela interface <literal>StatelessSession</literal> são considerados
operações diretas no banco de dados (row-level operations), isso resulta em uma
execução imediata de comandos SQL <literal>INSERT, UPDATE</literal> ou
<literal>DELETE</literal> respectivamente. Devido a isso, eles possuem uma
semântica bem diferente das operações <literal>save(), saveOrUpdate()</literal>
ou <literal>delete()</literal> definidas na interface <literal>Session</literal>.
</para>
</sect1>
<sect1 id="batch-direct" revision="3">
<title>Operações no estilo DML</title>
<para>
Como já discutido, mapeamento objeto/relacional automático e transparente é conseguido
com a gerência do estado do objeto. Com isto o estado daquele objeto fica disponível na
memória, manipulando(usando as expressões SQL <literal>Data Manipulation Language</literal>
(SQL-style DML): <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>)
os dados diretamente no banco de dados não irá afetar o estado registrado em memória.
Entretanto, o Hibernate provê métodos para executar queries SQL-style DML, que são
totalmente executas com HQL (Hibernate Query Language)
(<xref linkend="queryhql">HQL</xref>).
</para>
<para>
A pseudo-sintaxe para expressões <literal>UPDATE</literal> e <literal>DELETE</literal> é:
<literal>( UPDATE | DELETE ) FROM? NomeEntidade (WHERE condições_where)?</literal>.
Algumas observações:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Na clausula from, a palavra chave FROM é opcional;
</para>
</listitem>
<listitem>
<para>
Somente uma entidade pode ser chamada na clausula from; opcionalmente pode ter
um alias. Se o nome da entidade for possuir um alias, então qualquer propriedade
referenciada deve usar esse alias qualificado; se o nome da entidade não possuir
um alias, então nenhuma das propriedade precisa usar o acesso qualificado.
</para>
</listitem>
<listitem>
<para>
Na <xref linkend="queryhql-joins-forms">joins</xref> (ambas implícita ou explicita)
pode ser especificada em um bulk HQL query. Sub-queries podem ser usadas na clausula
where; as subqueries podem conter joins.
</para>
</listitem>
<listitem>
<para>
A clausula where também é opcional.
</para>
</listitem>
</itemizedlist>
<para>
Como exemplo para executar um HQL <literal>UPDATE</literal>, use o
método <literal>Query.executeUpdate()</literal>(o método ganhou o nome
devido a sua familiaridade com o do JDBC
<literal>PreparedStatement.executeUpdate()</literal>):
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
HQL <literal>UPDATE</literal> statements, by default do not effect the
<xref linkend="mapping-declaration-version">version</xref>
or the <xref linkend="mapping-declaration-timestamp">timestamp</xref> property values
for the affected entities; this is in keeping with the EJB3 specification. However,
you can force Hibernate to properly reset the <literal>version</literal> or
<literal>timestamp</literal> property values through the use of a <literal>versioned update</literal>.
This is achieved by adding the <literal>VERSIONED</literal> keyword after the <literal>UPDATE</literal>
keyword.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
Note that custom version types (<literal>org.hibernate.usertype.UserVersionType</literal>)
are not allowed in conjunction with a <literal>update versioned</literal> statement.
</para>
<para>
Para executar um HQL <literal>DELETE</literal>, use o mesmo método
<literal>Query.executeUpdate()</literal>:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer c where c.name = :oldName";
// or String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
O valor <literal>int</literal> retornado pelo método <literal>Query.executeUpdate()</literal>
indica o numero de entidade afetadas pela operação. Lembre-se que isso pode estar ou não
relacionado ao número de linhas alteradas no banco de dados. Uma operação bulk HQL pode resultar
em várias expressões SQL reais a serem executadas, por exemplo, no caso de joined-subclass.
O número retornado indica a quantidade real de entidades afetadas pela expressão. Voltando
ao exemplo da joined-subclass, a exclusão de uma das subclasses pode resultar numa
exclusão em outra tabelas, não apenas na tabela para qual a subclasses está mapeada, mas
também tabela "root" e possivelmente nas tabelas joined-subclass num nível hierárquico
imediatamente abaixo.
</para>
<para>
A pseudo-sintaxe para o comando <literal>INSERT</literal> é:
<literal>INSERT INTO EntityName properties_list select_statement</literal>. Alguns
pontos a observar:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Apenas a forma INSERT INTO ... SELECT ... é suportada; INSERT INTO ... VALUES ...
não é suportada.
</para>
<para>
A lista de propriedade é análoga à <literal>especificação da coluna</literal>
do comando SQL <literal>INSERT</literal>. Para entidades envolvidas em mapeamentos,
apenas a propriedades definidas diretamente a nível da classe podem ser usandas na
properties_list. Propriedades da superclass não são permitidas; e as propriedades
da subclasse não faz sentido. Em outras palavras, os comandos
<literal>INSERT</literal> não são polimorficos.
</para>
</listitem>
<listitem>
<para>
O camando select pode ser qualquer query HQL válida, que tenha um retorno compatível
com o tipo com o esperado pela inclusão. Atualmente, isto é verificado durante a compilação
da query, isto é melhor do que permitir que a verificação chegue ao banco de dados.
Entretanto perceba que isso pode causar problemas entre os <literal>Tipo</literal> do Hibernate
que são <emphasis>equivalentes</emphasis> em oposição a <emphasis>equal</emphasis>.
Isso pode causar problemas nas combinações entre a propriedade definida como
<literal>org.hibernate.type.DateType</literal>e um propriedade definida como
<literal>org.hibernate.type.TimestampType</literal>, embora o banco de dados não possa
fazer uma distinção ou possa ser capaz de manusear a conversão.
</para>
</listitem>
<listitem>
<para>
Para a propriedade id, a expressão insert oferece duas opções. Você pode especificar
qualquer propriedade id explicitamente no properties_list (em alguns casos esse valor
é obtido diretamente da expressão select) ou pode omitir do properties_list (nesse caso,
um valor gerado é usado). Essa ultima opção só é válida quando são usados geradores de ids
que operam no banco de dados; a tentativa de usar essa opção com geradores do tipo
"em memória" vai causar um exceção durante a etapa de parser. Veja a finalidades desta
discussão, os seguintes geradores operam com o banco de dados
<literal>org.hibernate.id.SequenceGenerator</literal> (e suas subclasses)
e qualquer implementação de <literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>.
Aqui, a exceção mais notável é o <literal>org.hibernate.id.TableHiLoGenerator</literal>, que
não pode ser usado porque ele não dispõe de mecanismos para recuperar o seu valor.
</para>
</listitem>
<listitem>
<para>
For properties mapped as either <literal>version</literal> or <literal>timestamp</literal>,
the insert statement gives you two options. You can either specify the property in the
properties_list (in which case its value is taken from the corresponding select expressions)
or omit it from the properties_list (in which case the <literal>seed value</literal> defined
by the <literal>org.hibernate.type.VersionType</literal> is used).
Para propriedades mapeadas como <literal>version</literal> ou <literal>timestamp</literal>,
a expressão insert oferece a você duas opções. Você pode especificar a propriedade na
properties_list (nesse caso o seu valor é obtido a partir da expressão select correspondente)
ou ele pode ser omitido da properties_list (neste caso o usa o <literal>valor semente</literal>
definido pela classe <literal>org.hibernate.type.VersionType</literal>).
</para>
</listitem>
</itemizedlist>
<para>
Exemplo da execução de um HQL <literal>INSERT</literal>:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
int createdEntities = s.createQuery( hqlInsert )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
</sect1>
</chapter>
<chapter id="batch">
<title>Processamento de lotes</title>
<para>
Uma alternativa para inserir 100.000 linhas no banco de dados usando o Hibernate
pode ser a seguinte:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();]]></programlisting>
<para>
Isto irá falhar em algum lugar próximo a linha 50.000, lançando uma
<literal>OutOfMemoryException</literal>. Isso ocorre devido ao fato do Hibernate
fazer cache de todas as instâncias de <literal>Customer</literal> inseridas num
cachê em nível de sessão.
</para>
<para>
Neste capítulo veremos como contornar esse problema. Entretanto, se você vai realizar
processamento de lotes, é muito importante que você habilite o uso de lotes JDBC, se
você pretende obter um desempenho razoável. Defina o tamanho do lote JDBC em um
valor razoável (algo entre 10-50):
</para>
<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
<para>
Você também pode querer rodar esse tipo de processamento de lotes com o cache
secundário completamente desabilitado:
</para>
<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
<para id="disablebatching" revision="1">
Note that Hibernate disables insert batching at the JDBC level transparently if you
use an <literal>identiy</literal> identifier generator.
</para>
<para>
Mas isto não é absolutamente necessário, desde que nós possamos ajustar o
<literal>CacheMode</literal> para desabilitar a interação com o cache secundário.
</para>
<sect1 id="batch-inserts">
<title>Inserção de lotes</title>
<para>
Quando você estiver inserindo novos objetos persistentes, vocês deve executar
os métodos <literal>flush()</literal> e <literal>clear()</literal> regularmente
na sessão, para controlar o tamanho do cache primário.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();]]></programlisting>
</sect1>
<sect1 id="batch-update" >
<title>Batch updates</title>
<para>
Para recuperar e atualizar informações a mesma idéia é válida. Adicionalmente,
pode precisar usar o <literal>scroll()</literal> para usar recursos no lado
do servidor em queries que retornam muita informação.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
if ( ++count % 20 == 0 ) {
//flush a batch of updates and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();]]></programlisting>
</sect1>
<sect1 id="batch-statelesssession">
<title>A interface StatelessSession</title>
<para>
Alternativamente, o Hibernate provê uma API orientada à comandos, usada para
transmitir um fluxo de dados de e para o banco de dados na forma de objetos soltos.
Uma <literal>StatelessSession</literal> não tem um contexto persistente associado e
não fornece muito das semânticas de alto nível para controle do ciclo de vida.
Em especial, uma StatelessSession não implemente o cache primário e nem interage
com o cache secundário ou query cache. Ele não implementa salvamento transacional
automatico ou checagem automática de mudanças. Operação realizadas usando uma
StatelessSession não fazem nenhum tipo de cascade com as instancias associadas.
As coleções são ignoradas por uma StatelessSession. Operações realizadas com um
StatelessSession ignoram a arquitetura de eventos e os interceptadores.
StatelessSession são vulneráveis aos efeitos do aliasing dos dados, devido a
falta do cache primário. Uma StatelessSession é uma abstração de baixo nível,
muito mais próxima do JDBC.
</para>
<programlisting><![CDATA[StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
session.update(customer);
}
tx.commit();
session.close();]]></programlisting>
<para>
Veja neste exempo, as instancias de <literal>Customer</literal> retornadas pela query
são imediatamente desvinculadas. Elas nunca serão assossiadas à um contexto persistente.
</para>
<para>
As operações <literal>insert(), update()</literal> e <literal>delete()</literal>
definidos pela interface <literal>StatelessSession</literal> são considerados
operações diretas no banco de dados (row-level operations), isso resulta em uma
execução imediata de comandos SQL <literal>INSERT, UPDATE</literal> ou
<literal>DELETE</literal> respectivamente. Devido a isso, eles possuem uma
semântica bem diferente das operações <literal>save(), saveOrUpdate()</literal>
ou <literal>delete()</literal> definidas na interface <literal>Session</literal>.
</para>
</sect1>
<sect1 id="batch-direct" revision="3">
<title>Operações no estilo DML</title>
<para>
Como já discutido, mapeamento objeto/relacional automático e transparente é conseguido
com a gerência do estado do objeto. Com isto o estado daquele objeto fica disponível na
memória, manipulando(usando as expressões SQL <literal>Data Manipulation Language</literal>
(SQL-style DML): <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>)
os dados diretamente no banco de dados não irá afetar o estado registrado em memória.
Entretanto, o Hibernate provê métodos para executar queries SQL-style DML, que são
totalmente executas com HQL (Hibernate Query Language)
(<xref linkend="queryhql">HQL</xref>).
</para>
<para>
A pseudo-sintaxe para expressões <literal>UPDATE</literal> e <literal>DELETE</literal> é:
<literal>( UPDATE | DELETE ) FROM? NomeEntidade (WHERE condições_where)?</literal>.
Algumas observações:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Na clausula from, a palavra chave FROM é opcional;
</para>
</listitem>
<listitem>
<para>
Somente uma entidade pode ser chamada na clausula from; opcionalmente pode ter
um alias. Se o nome da entidade for possuir um alias, então qualquer propriedade
referenciada deve usar esse alias qualificado; se o nome da entidade não possuir
um alias, então nenhuma das propriedade precisa usar o acesso qualificado.
</para>
</listitem>
<listitem>
<para>
Na <xref linkend="queryhql-joins-forms">joins</xref> (ambas implícita ou explicita)
pode ser especificada em um bulk HQL query. Sub-queries podem ser usadas na clausula
where; as subqueries podem conter joins.
</para>
</listitem>
<listitem>
<para>
A clausula where também é opcional.
</para>
</listitem>
</itemizedlist>
<para>
Como exemplo para executar um HQL <literal>UPDATE</literal>, use o
método <literal>Query.executeUpdate()</literal>(o método ganhou o nome
devido a sua familiaridade com o do JDBC
<literal>PreparedStatement.executeUpdate()</literal>):
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
HQL <literal>UPDATE</literal> statements, by default do not effect the
<xref linkend="mapping-declaration-version">version</xref>
or the <xref linkend="mapping-declaration-timestamp">timestamp</xref> property values
for the affected entities; this is in keeping with the EJB3 specification. However,
you can force Hibernate to properly reset the <literal>version</literal> or
<literal>timestamp</literal> property values through the use of a <literal>versioned update</literal>.
This is achieved by adding the <literal>VERSIONED</literal> keyword after the <literal>UPDATE</literal>
keyword.
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
Note that custom version types (<literal>org.hibernate.usertype.UserVersionType</literal>)
are not allowed in conjunction with a <literal>update versioned</literal> statement.
</para>
<para>
Para executar um HQL <literal>DELETE</literal>, use o mesmo método
<literal>Query.executeUpdate()</literal>:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer c where c.name = :oldName";
// or String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
<para>
O valor <literal>int</literal> retornado pelo método <literal>Query.executeUpdate()</literal>
indica o numero de entidade afetadas pela operação. Lembre-se que isso pode estar ou não
relacionado ao número de linhas alteradas no banco de dados. Uma operação bulk HQL pode resultar
em várias expressões SQL reais a serem executadas, por exemplo, no caso de joined-subclass.
O número retornado indica a quantidade real de entidades afetadas pela expressão. Voltando
ao exemplo da joined-subclass, a exclusão de uma das subclasses pode resultar numa
exclusão em outra tabelas, não apenas na tabela para qual a subclasses está mapeada, mas
também tabela "root" e possivelmente nas tabelas joined-subclass num nível hierárquico
imediatamente abaixo.
</para>
<para>
A pseudo-sintaxe para o comando <literal>INSERT</literal> é:
<literal>INSERT INTO EntityName properties_list select_statement</literal>. Alguns
pontos a observar:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Apenas a forma INSERT INTO ... SELECT ... é suportada; INSERT INTO ... VALUES ...
não é suportada.
</para>
<para>
A lista de propriedade é análoga à <literal>especificação da coluna</literal>
do comando SQL <literal>INSERT</literal>. Para entidades envolvidas em mapeamentos,
apenas a propriedades definidas diretamente a nível da classe podem ser usandas na
properties_list. Propriedades da superclass não são permitidas; e as propriedades
da subclasse não faz sentido. Em outras palavras, os comandos
<literal>INSERT</literal> não são polimorficos.
</para>
</listitem>
<listitem>
<para>
O camando select pode ser qualquer query HQL válida, que tenha um retorno compatível
com o tipo com o esperado pela inclusão. Atualmente, isto é verificado durante a compilação
da query, isto é melhor do que permitir que a verificação chegue ao banco de dados.
Entretanto perceba que isso pode causar problemas entre os <literal>Tipo</literal> do Hibernate
que são <emphasis>equivalentes</emphasis> em oposição a <emphasis>equal</emphasis>.
Isso pode causar problemas nas combinações entre a propriedade definida como
<literal>org.hibernate.type.DateType</literal>e um propriedade definida como
<literal>org.hibernate.type.TimestampType</literal>, embora o banco de dados não possa
fazer uma distinção ou possa ser capaz de manusear a conversão.
</para>
</listitem>
<listitem>
<para>
Para a propriedade id, a expressão insert oferece duas opções. Você pode especificar
qualquer propriedade id explicitamente no properties_list (em alguns casos esse valor
é obtido diretamente da expressão select) ou pode omitir do properties_list (nesse caso,
um valor gerado é usado). Essa ultima opção só é válida quando são usados geradores de ids
que operam no banco de dados; a tentativa de usar essa opção com geradores do tipo
"em memória" vai causar um exceção durante a etapa de parser. Veja a finalidades desta
discussão, os seguintes geradores operam com o banco de dados
<literal>org.hibernate.id.SequenceGenerator</literal> (e suas subclasses)
e qualquer implementação de <literal>org.hibernate.id.PostInsertIdentifierGenerator</literal>.
Aqui, a exceção mais notável é o <literal>org.hibernate.id.TableHiLoGenerator</literal>, que
não pode ser usado porque ele não dispõe de mecanismos para recuperar o seu valor.
</para>
</listitem>
<listitem>
<para>
For properties mapped as either <literal>version</literal> or <literal>timestamp</literal>,
the insert statement gives you two options. You can either specify the property in the
properties_list (in which case its value is taken from the corresponding select expressions)
or omit it from the properties_list (in which case the <literal>seed value</literal> defined
by the <literal>org.hibernate.type.VersionType</literal> is used).
Para propriedades mapeadas como <literal>version</literal> ou <literal>timestamp</literal>,
a expressão insert oferece a você duas opções. Você pode especificar a propriedade na
properties_list (nesse caso o seu valor é obtido a partir da expressão select correspondente)
ou ele pode ser omitido da properties_list (neste caso o usa o <literal>valor semente</literal>
definido pela classe <literal>org.hibernate.type.VersionType</literal>).
</para>
</listitem>
</itemizedlist>
<para>
Exemplo da execução de um HQL <literal>INSERT</literal>:
</para>
<programlisting><![CDATA[Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
int createdEntities = s.createQuery( hqlInsert )
.executeUpdate();
tx.commit();
session.close();]]></programlisting>
</sect1>
</chapter>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="best-practices" revision="3">
<chapter id="best-practices" revision="3">
<title>Boas práticas</title>
<variablelist spacing="compact">

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="collections">
<chapter id="collections">
<title>Mapeamento de Coleções</title>
<sect1 id="collections-persistent" revision="3">

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="components">
<chapter id="components">
<title>Mapeamento de Componentes</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="events">
<chapter id="events">
<title>Interceptadores e Eventos</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="example-mappings">
<chapter id="example-mappings">
<title>Exemplo: Vários Mapeamentos</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="example-parentchild">
<chapter id="example-parentchild">
<title>Example: Parent/Child</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="example-weblog">
<chapter id="example-weblog">
<title>Example: Weblog Application</title>
<sect1 id="example-weblog-classes">

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="filters">
<chapter id="filters">
<title>Filtrando dados</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="inheritance">
<chapter id="inheritance">
<title>Mapeamento de Herança</title>
<sect1 id="inheritance-strategies" revision="3">

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="performance">
<chapter id="performance">
<title>Aumentando a performance</title>
<sect1 id="performance-fetching" revision="2">

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="persistent-classes" revision="2">
<chapter id="persistent-classes" revision="2">
<title>Persistent Classes</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<preface id="preface" revision="2">
<preface id="preface" revision="2">
<title>Prefácio</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="querycriteria">
<chapter id="querycriteria">
<title>Consultas por critérios</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="querysql" revision="2">
<chapter id="querysql" revision="2">
<title>Native SQL</title>
<para>You may also express queries in the native SQL dialect of your

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="toolsetguide" revision="2">
<chapter id="toolsetguide" revision="2">
<title>Toolset Guide</title>
<para>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="xml">
<chapter id="xml">
<title>Mapeamento XML</title>
<para><emphasis>