From hibernate-commits at lists.jboss.org Thu Oct 25 20:48:55 2007 Content-Type: multipart/mixed; boundary="===============0672044846751291962==" MIME-Version: 1.0 From: hibernate-commits at lists.jboss.org To: hibernate-commits at lists.jboss.org Subject: [hibernate-commits] Hibernate SVN: r14136 - core/trunk/documentation/manual/pt-BR/src/main/docbook/content. Date: Thu, 25 Oct 2007 20:48:49 -0400 Message-ID: --===============0672044846751291962== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: xhuang(a)jboss.com Date: 2007-10-25 20:48:48 -0400 (Thu, 25 Oct 2007) New Revision: 14136 Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/associati= on_mapping.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_map= ping.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_prac= tices.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collectio= n_mapping.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/component= _mapping.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configura= tion.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_m= appings.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_p= arentchild.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_w= eblog.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.x= ml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inheritan= ce_mapping.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performan= ce.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persisten= t_classes.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.x= ml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_cri= teria.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hql= .xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sql= .xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_a= pi.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_g= uide.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transacti= ons.xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial.= xml core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml Log: Remove ^M characters, match with latest English XML Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/as= sociation_mapping.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/associat= ion_mapping.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/associat= ion_mapping.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + = Mapeamento de Associa=C3=A7=C3=B5es = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ba= sic_mapping.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_ma= pping.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/basic_ma= pping.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,3494 +1,3660 @@ = -=EF=BB=BF=EF=BB=BF - Mapeamento O/R Bassico - - - Declara=C3=A7=C3=A3o de mapeamento - - - Object/relational mappings are usually defined in an XML docum= ent. The mapping - document is designed to be readable and hand-editable. The map= ping language is - Java-centric, meaning that mappings are constructed around per= sistent class - declarations, not table declarations. - - = - - Note that, even though many Hibernate users choose to write th= e XML by hand, - a number of tools exist to generate the mapping document, incl= uding XDoclet, - Middlegen and AndroMDA. - - - - Lets kick off with an example mapping: - - - - - - - - - = - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - Discutir agora o conte=C3=BAdo deste documento de mapeamento.= Iremos apenas descrever = - os elementos do documento e atributos que s=C3=A3o utilizados= pelo Hibernate em tempo = - de execu=C3=A7=C3=A3o. O documento de mapeamento tamb=C3=A9m = cont=C3=A9m alguns atributos adicionais = - e opcionais al=C3=A9m de elementos que afetam os esquemas de = banco de dados exportados = - pela ferramenta de exporta=C3=A7=C3=A3o de esquemas. (Por exe= mplo, o atributo = - not-null). - - - - - - Doctype - - - Todos os mapeamentos de XML devem declarar o doctype exibi= do. O DTD atual pode = - ser encontrado na URL abaixo, no diret=C3=B3rio h= ibernate-x.x.x/src/org/ - hibernate ou no hibernate3.jar. O Hibernate sempre = - ir=C3=A1 procurar pelo DTD inicialmente no seu classpath. = Se voc=C3=AA tentar localizar - o DTD usando uma conex=C3=A3o de internet, compare a decla= ra=C3=A7=C3=A3o do seu DTD com o = - conte=C3=BAdo do seu classpath - - - - EntityResolver - - As mentioned previously, Hibernate will first attempt = to resolve DTDs in its classpath. The - manner in which it does this is by registering a custo= m org.xml.sax.EntityResolver - implementation with the SAXReader it uses to read in t= he xml files. This custom - EntityResolver recognizes two diffe= rent systemId namespaces. - - - - - a hibernate namespace is re= cognized whenever the - resolver encounteres a systemId starting with - http://hibernate.sourceforge.net/; the resolver - attempts to resolve these entities via the cla= sslaoder which loaded - the Hibernate classes. - - - - - a user namespace is recogni= zed whenever the - resolver encounteres a systemId using a classpath:// - URL protocol; the resolver will attempt to res= olve these entities - via (1) the current thread context classloader= and (2) the - classloader which loaded the Hibernate classes. - - - - - An example of utilizing user namespacing: - - - -]> - - - - - ... - - - &types; -]]> - - Where types.xml is a resource in th= e your.domain - package and contains a custom typedef. - - - - - - hibernate-mapping - - - Este elemento tem diversos atributos opcionais. Os atribut= os = - schema e catalog esp= ecificam que tabelas = - referenciadas neste mapeamento pertencem ao esquema e/ou a= o catalogo nomeado. = - Se especificados, os nomes das tabelas ir=C3=A3o ser quali= ficados no schema ou catalog dado. = - Se n=C3=A3o, os nomes das tabelas n=C3=A3o ser=C3=A3o qual= ificados. O atributo default-cascade - especifica qual estilo de cascata ser=C3=A1 ass= umido pelas propriedades e = - cole=C3=A7=C3=B5es que n=C3=A3o especificarm um atributo <= literal>cascade. O atributo = - auto-import nos deixa utilizar nomes de= classes n=C3=A3o qualificados = - na linguagem de consulta, por default. - - = - - - - - - - - - - - ]]> - - - - schema (opcional): O nome = do esquema do banco de dados. - - - - - catalog (opcional): O nom= e do cat=C3=A1logo do banco de dados. - - - - - default-cascade (opcional = =E2=80=93 default =C3=A9 nenhum - ): Um estilo cascata default. - - - - - default-access (opcional = =E2=80=93 default =C3=A9 property): = - A estrat=C3=A9gia que o Hibernate deve utiliz= ar para acessar todas as propridades. Pode = - ser uma implementa=C3=A7=C3=A3o pr=C3=B3pria = de PropertyAccessor. - - - - - default-lazy (opcional - d= efault =C3=A9 true): = - O valor default para atributos lazy<= /literal> da classe e dos = - mapeamentos de cole=C3=A7=C3=B5es. - - - - - auto-import ((opcional - d= efault =C3=A9 true): - Especifica se n=C3=B3s podemos usar nomes de = classess n=C3=A3o qualificados = - (das classes deste mapeamento) na linguagem d= e consulta. - - - - - package (opcional): Especi= fica um prefixo da package para = - assumir para nomes de classes n=C3=A3o qualif= icadas no documento de mapeamento. - - - - - = - - Se voce tem duas classes persistentes com o mesmo nome (n= =C3=A3o qualificadas), voc=C3=AA deve = - setar auto-import=3D"false". O Hiberna= te ir=C3=A1 gerar uma exce=C3=A7=C3=A3o se = - voc=C3=AA tentar setar duas classes para o mesmo nome "im= portado". - - - - Observe que o elemento hibernate-mapping permite a voc=C3=AA = - aninhar diversos mapeamentos de <class> persistentes, = - como mostrado abaixo. Entretanto, =C3=A9 uma boa pr=C3=A1= tica (e esperado por algumas = - ferramentas)o mapeamento de apenas uma classe persistente= simples (ou uma = - hierarquia de classes simples) em um arquivo de mapeament= o e nomea-la ap=C3=B3s = - a superclasse persistente, por exemplo: Cat.hbm.= xml, = - Dog.hbm.xml, ou se estiver usando her= an=C3=A7a, - Animal.hbm.xml. - - = - - - - class - - - Voc=C3=AA pode declarar uma classe persistente utilizando = o elemento - class: - - = - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - name (opcional): O nome da = classe Java inteiramente qualificado - da classe persistente (ou interface); Se o atr= ibuto =C3=A9 ausente, assume-se que o = - mapeamento =C3=A9 para intidades n=C3=A3o-POJO. - - - - - table (opcional =E2=80=93 d= efault para nomes de classes n=C3=A3o = - qualificadas) O nome da sua tabela do banco de= dados. - - - - - discriminator-value (opcion= al =E2=80=93 default para o nome da classe): = - Um valor que distingue subclasses individuais,= usadas para o comportamento polimorfico. = - Valores aceitos incluem null e not null - - - - - mutable (opcional - valor d= efault true): = - Especifica que instancias da classe s=C3=A3o (= ou n=C3=A3o) mut=C3=A1veis - - = - - - schema (opcional): Sobrep= =C3=B5e o nome do esquema especificado = - pelo elemento root <hibernate-mapp= ing>. - - = - - - catalog (opcional): Sobrep= =C3=B5e o nome do cat=C3=A1logo especificado = - pelo elemento root <hibernate-map= ping>. = - - = - - - proxy (opcional): Especific= a um interface para ser = - utilizada pelos proxies de inicializa=C3=A7=C3= =A3o tardia. Voc=C3=AA pode especificar o = - nome da pr=C3=B3pria classe. - - = - - - dynamic-update (opcional, v= alor default false): = - Especifica que o SQL de UPDATE deve ser gerado em tempo de = - execu=C3=A7=C3=A3o e conter apenas aquelas col= unas cujos valores foram alterados. - - = - - - dynamic-insert (opcional, v= alor default false): = - Especifica que o SQL de INSERT deve ser gerado em tempo de = - execu=C3=A7=C3=A3o e conter apenas aquelas col= unas cujos valores n=C3=A3o est=C3=A3o nulos. - - = - - - select-before-update (opci= onal, valor default false): = - Especifica que o Hibernate never deve executar um SQL de = - UPDATE a n=C3=A3o ser que c= om certeza um objeto est=C3=A1 atualmente modificado. = - Em certos casos (atualmente, apenas quando um = objeto transiente foi associado com uma nova - sess=C3=A3o utilizando update()), isto significa que o Hibernate ira executar = - uma instru=C3=A7=C3=A3o SQL de SELECT= adicional para determinar se um = - UPDATE =C3=A9 necess=C3=A1r= io nesse momento. - - = - - - polymorphism (opcional, def= ault para implicit): = - Determina se deve ser utilizado a query polimo= rfica implicita ou explicitamente. - - = - - - where (opicional) especific= a um comando SQL WHERE - arbitr=C3=A1rio para ser usado quando da recup= era=C3=A7=C3=A3o de objetos desta classe. - - = - - - persister (opcional): Espei= cifca uma ClassPersister = - customizada. - - = - - - batch-size (opcional, valor= default 1) especifica um = - "tamanho de lote" para a recupera=C3=A7=C3=A3o= de instancias desta classe pelo identificador. - - = - - - optimistic-lock (octional, = valor default version): = - Determina a estrat=C3=A9gia de bloqueio. - - = - - - lazy (opcional): A recupera= =C3=A7=C3=A3o tardia pode ser completamente = - desabilitada, setando lazy=3D"false"<= /literal>. - - = - - - entity-name (opcional, defa= ult para o nome da classe): O = - Hibernate3 permite uma classe ser mapeada mult= iplas vezes, (potencialmente,para = - diferentes tabelas), e permite mapeamentos de = entidades que s=C3=A3o representadas = - por Maps ou XML no n=C3=ADvel Java. Nestes cas= os, voc=C3=AA deve especificar um nome = - arbitr=C3=A1rio explicitamente para a entidade= . Veja = - e para maiores informa= =C3=A7=C3=B5es. - - - - - check (opcional): Uma expre= ss=C3=A3o SQL utilizada para gerar uma = - constraint de verifica=C3=A7=C3=A3o<= /emphasis> de m=C3=BAltiplas linhas para a gera=C3=A7=C3=A3o = - autom=C3=A1tica do esquema. - - - - - rowid (opcional): O Hiberna= te poder usar as assim chamadas = - ROWIDs em bancos de dados que a suportam. Por = exemplo, no Oracle, o Hibernate = - pode utilizar a coluna extra rowid para atuali= za=C3=A7=C3=B5es mais r=C3=A1pidas se voc=C3=AA = - configurar esta op=C3=A7=C3=A3o para = rowid. Um ROWID =C3=A9 uma implementa=C3=A7=C3=A3o = - que representa de maneira detalhada a localiza= =C3=A7=C3=A3o f=C3=ADsica de uma determinada = - tupla armazenado. - - - - - subselect (optional): Maps = an immutable and read-only entity - to a database subselect. Useful if you want to= have a view instead of a base table, - but don't. See below for more information. - subselect (opcional): Mapei= a uma entidade imutavel e somente - de leitura para um subconjunto do banco de da= dos. =C3=9Atil se voc=C3=AA quiser ter uma = - view em vez de uma tabela. Veja abaixo para ma= is informa=C3=A7=C3=B5es. - - - - - abstract (opcional): Utiliz= ada para marcar superclasses = - abstratas em hierarquias <union-su= bclass>. - - - - - = - - =C3=89 perfeitamente aceit=C3=A1vel para uma classe persit= ente nomeada ser uma interface. Voc=C3=AA dever=C3=A1 = - ent=C3=A3o declarar as classes implementadas desta interfa= ce utilizando o elemento = - <subclass>. Voc=C3=AA pode persis= tir qualquer classe de aninhada - estatica. Voc=C3=AA dever=C3=A1 espec= ificar o nome da classe usando a forma = - padr=C3=A3o, por exemplo: eg.Foo$Bar. - - - - Classes imut=C3=A1veis, mutable=3D"false", n=C3=A3o podem ser modificadas ou exclu=C3=ADdas = - pela aplica=C3=A7=C3=A3o. Isso permite ao Hibernate fazer = alguns aperfei=C3=A7oamentos de performance. - - = - - O atributo opcional proxy habilita a in= icializa=C3=A7=C3=A3o tardia das = - inst=C3=A2ncias persistentes da classe. O Hibernate ir=C3= =A1 retornar CGLIB proxies como implementado = - na interface nomeada. O objeto persistente atual ser=C3= =A1 carregado quando um m=C3=A9todo do proxy = - for invocado. Veja "Inicializando cole=C3=A7=C3=B5es e pro= xies" abaixo. - - = - Polimorfismo impl=C3=ADcito signifi= ca que inst=C3=A2ncias de uma classe = - ser=C3=A3o retornada por uma query que d=C3=A1 nome a qual= quer superclasse ou interface implementada, = - ou a classe e as instancias de qualquer subclasse da class= e ser=C3=A1 retornada por umq query = - que nomeia a classe por si. Polimorfismo expl=C3= =ADcito significa que = - instancias da classe ser=C3=A3o retornadas apenas por quer= ies que explicitamente nomeiam a = - classe e que queries que nomeiam as classes ir=C3=A3o reto= rnar apenas instancias de subclasses = - mapeadas dentro da declara=C3=A7=C3=A3o <class= > como uma = - <subclass> ou <joined= -subclass>. - Para a maioria dos casos, o valor default polymor= phism=3D"implicit", = - =C3=A9 apropriado. Polimorfismo explicito =C3=A9 =C3=BAtil= quando duas classes distintas est=C3=A3o mapeadas = - para a mesma tabela (isso permite um classe "peso leve" qu= e contem um subconjunto = - de colunas da tabela). - - = - - O atributo persister deixa voc=C3=AA cu= stomizar a estrat=C3=A9gia de persist=C3=AAncia = - utilizada para a classe. Voc=C3=AA pode, por exemplo, espe= cificar sua pr=C3=B3rpia subclasse do = - org.hibernate.persister.EntityPersister= ou voc=C3=AA pode criar = - uma implementa=C3=A7=C3=A3o completamente nova da interfa= ce = - org.hibernate.persister.ClassPersister = que implementa a persist=C3=AAncia = - atrav=C3=A9s de, por exemplo, chamadas a stored procedeure= s, serializa=C3=A7=C3=A3o de arquivos flat ou = - LDAP. Veja org.hibernate.test.CustomPersister para um exemplo = - simples (de "persistencia" para uma Hashtable). - - = - - Observe que as configura=C3=A7=C3=B5es dynamic-up= date e = - dynamic-insert n=C3=A3o sao herdadas pe= las subclasses e assim podem tambem = - ser especificadas em elementos <subclass> or = - <joined-subclass>. Estas configur= a=C3=A7=C3=B5es podem incrementar a = - performance em alguns casos, mas pode realmente diminuir a= performance em outras. = - Use-as de forma bastante criteriosa. - - = - - O uso de select-before-update geralment= e ir=C3=A1 diminuir a performance. Ela =C3=A9 = - muito =C3=BAtil para prevenir que uma trigger de atualiza= =C3=A7=C3=A3o no banco de dados seja ativada = - desnecessariamente, se voc=C3=AA reconectar um n=C3=B3 de = uma instancia desconectada em uma = - Session. - - = - - Se voc=C3=AA ativar dynamic-update, vo= c=C3=AA ter=C3=A1 de escolher = - a estrat=C3=A9gia de bloqueio otimista: - - - - - version verifica a vers=C3=A3o = e a hora das colunas - - - - - all cverifica todas as colunas - - - - - dirty verifica as colunas modif= icadas, permitindo = - alguns updates concorrentes - - - - - none n=C3=A3o utiliza o bloquei= o otimista - - - - - N=C3=B3s recomendamos com muita enfas= e que voc=C3=AA utilize a = - vers=C3=A3o e a hora das colunas para o bloqueio otimista = com o Hibernate. = - Esta =C3=A9 a melhor estrat=C3=A9gia com respeito a perfor= mance e =C3=A9 a =C3=BAnica estrat=C3=A9gia = - que trata corretamente as modifica=C3=A7=C3=B5es efetuadas= em instancias desconectadas = - (por exemplo, quando Session.merge() = =C3=A9 utilizado). - - - - - N=C3=A3o ha diferen=C3=A7a entre uma view e uma tabela par= a o mapeamento do Hibernate, e como = - esperado isto =C3=A9 transparente no n=C3=ADvel do banco d= e dados (observe que alguns bancos de = - dados n=C3=A3o suportam views apropriadamente, especialmen= te com updates). Algumas vezes, = - voc=C3=AA quer utilizar uma view, ma sn=C3=A3o pode cria-l= a no banco de dados (por exemplo, = - com um esquema legado). Neste caso, voc=C3=AA pode mapear = uma entidade imut=C3=A1vel e de = - somente leitura, para uma dada express=C3=A3o SQL, que rep= resenta um subselect: - - - - - select item.name, max(bid.amount), count(*) - from item - join bid on bid.item_id =3D item.id - group by item.name - - - - - ... -]]> - - - Declare as tabelas para sincronizar com esta entidade, gar= antindo que o auto-flush = - ocorra corretamente, e que as queries para esta entidade d= erivada n=C3=A3o retornem dados = - desatualizados. O <subselect> est= =C3=A1 dispon=C3=ADvel tanto como um = - atributo como um elemento mapeado nested. - - - - - - id - - - Classes mapeadas precisam declarar a = coluna de chave primaria da = - tabela do banco de dados. Muitas classes ir=C3=A3o tambem = ter uma propriedade ao estilo = - Java-Beans declarando o identificador unico de uma instanc= ia. O elemento = - <id> define o mapeamento desta pr= opriedade para a chave prim=C3=A1ria. - - = - - - - - - - - - - node=3D"element-name|@attribute-name|element/@attribute|." - - -]]> - - - - name (opcional): O nome do = identificador. - - - - - type (opcional): Um nome qu= e indica o tipo no Hibernate. - - - - - column (opcional =E2=80=93 = default para o a propridade name): O = - nome coluna chave primaria. - - - - - unsaved-value (opcional - d= efault para um valor "sens=C3=ADvel"): = - Uma propriedade de identifica=C3=A7=C3=A3o que= indica que a instancia foi novamente = - instanciada (unsaved), diferenciando de instan= cias desconectadas que foram = - salvas ou carregadas em uma sess=C3=A3o anteri= or. - - = - - - access (opcional - valor de= fault property): A = - estrat=C3=A9gia que o Hiberante deve utilizar = para acessar o valor da propriedade - - - - - = - - Se o atributo name n=C3=A3o for declara= do, assume-se que a classe n=C3=A3o tem = - a propriedade de identifica=C3=A7=C3=A3o. - - = - - O atributo unsaved-value n=C3=A3o =C3= =A9 mais necess=C3=A1rio no Hibernate 3. - - - - H=C3=A1 declara=C3=A7=C3=A3o alternativa <com= posite-id> permite o acesso a = - dados legados com chaves compostas. N=C3=B3s desencorajamo= s fortemente o seu uso por = - qualquer pessoa. - - = - - Generator - - - O elemento filho opcional <generator> nomeia uma classe Java = - usada para gerar identificadores unicos para instancia= s de uma classe persistente. = - Se algum par=C3=A2metro =C3=A9 requerido para configur= ar ou inicializar a instancia geradora, = - eles s=C3=A3o passados utilizando o elemento = <param>. - - - - - uid_table - next_hi_value_column - -]]> - - - Todos os generators implementam a interface = org.hibernate.id.IdentifierGenerator. = - Esta =C3=A9 uma interface bem simples; algumas aplica= =C3=A7=C3=B5es podem prover sua pr=C3=B3pria implementa=C3=A7=C3=A3o = - esepecializada. Entretanto, o Hibernate disponibiliza = um conjunto de implementa=C3=A7=C3=B5es internamente. = - H=C3=A1 nomes de atalhos para estes generators pr=C3= =B3prios: - - - increment - - - gera identificadores dos tipos lo= ng, short ou - int que s=C3=A3o unicos= apenas quando nenhum outro processo est=C3=A1 = - inserindo dados na mesma tabela. N=C3=A3o utilize em ambientes = - de cluster. - - - - - identity - - - suporta colunas de identidade em DB2, MyS= QL, MS SQL Server, Sybase e = - HypersonicSQL. O identificador retornado = =C3=A9 do tipo long, = - short ou int. - - - - - sequence - - - utiliza uma sequence em DB2, PostgreSQL, O= racle, SAP DB, McKoi ou um = - generator no Interbase. O identificador de= retorno =C3=A9 do tipo - long, short o= u int. - - - - - hilo - - - utiliza um algoritmo hi/lo para gerar de f= orma eficiente identificadores do tipo = - long, short ou int, - a partir de uma tabela e coluna fornecida = (por default = - hibernate_unique_key e = next_hi) = - como fonte para os valores hi. O algoritmo= hi/lo gera identificadores que s=C3=A3o = - =C3=BAnicos apenas para um banco de dados = particular. = - - - - - seqhilo - - - utiliza um algoritmo hi/lo para gerar de f= orma eficinete identificadores do tipo = - long, short ou int, - a partir de uma sequence de banco de dados= fornecida. - - - - - uuid - - - utiliza um algortimo UUID de 128-bits para= gerar identificadores do = - tipo string, unicos em uma rede(o endere= =C3=A7o IP =C3=A9 utilizado). O UUID =C3=A9 = - codificado como um string de digitos hexad= ecimais de tamanho 32. - - - - - guid - - - utiliza um string GUID gerado pelo banco d= e dados no MS SQL Server = - e MySQL. - - - - - native - - - seleciona entre identity, sequence = - ou hilo dependendo das = capacidades do banco de dados = - utilizado. - - - - - assigned - - - deixa a aplica=C3=A7=C3=A3o definir um ide= ntificador para o objeto antes que o = - save() seja chamado. Es= ta =C3=A9 a estrat=C3=A9gia default = - se nenhum elemento <generator&= gt; =C3=A9 especificado. - - - - - select - - - retorna a chave primaria recuperada por um= a trigger do banco de = - dados, selecionado uma linha pela chave = =C3=BAnica e recuperando o valor = - da chave prim=C3=A1ria. - - - - - foreign - - - utiliza o identificador de um outro objeto= associado. Normalmente utilizado = - em conjunto com uma associa=C3=A7=C3=B5a d= e chave prim=C3=A1ria do tipo - <one-to-one>. - - - - - sequence-identity - - - a specialized sequence generation strategy= which utilizes a - database sequence for the actual value gen= eration, but combines - this with JDBC3 getGeneratedKeys to actual= ly return the generated - identifier value as part of the insert sta= tement execution. This - strategy is only known to be supported on = Oracle 10g drivers - targetted for JDK 1.4. Note comments on t= hese insert statements - are disabled due to a bug in the Oracle dr= ivers. - - - - - - - - = - - Algoritmo Hi/lo - - Os geradores hilo e seqhil= o fornecem duas = - implementa=C3=A7=C3=B5es alternativas do algoritmo hi/= lo, uma solu=C3=A7=C3=A3o preferencial para a gera=C3=A7=C3=A3o = - de identificadores. A primeira implementa=C3=A7=C3=A3o= requer uma tabela especial do banco de = - dados para manter o proximo valor "hi" dispon=C3=ADvel= . A segunda utiliza uma seq=C3=BC=C3=AAncia = - do estilo Oracle (quando suportado). = - - - - - hi_value - next_value - 100 - -]]> - - - - hi_value - 100 - -]]> - - - Infelizemente, voce n=C3=A3o pode utilizar hi= lo quando estiver = - fornecendo sia propria Connection = para o Hibernate. Quando o = - Hibernate est=C3=A1 usando um datasource do servidor d= e aplica=C3=A7=C3=B5es para obter conex=C3=B5es = - suportadas com JTA, voc=C3=AA precisa configurar adequ= adamente o = - hibernate.transaction.manager_lookup_class. - - - = - - UUID algorithm - - O UUID contem: o endere=C3=A7o IP, hora de inicio da J= VM (com precis=C3=A3o de um quarto = - de segundo), a hora do sistema e um valor contador (un= ico dentro da JVM). = - N=C3=A3o =C3=A9 possivel obter o endere=C3=A7o MAC ou = um endere=C3=A7o de mem=C3=B3ria do c=C3=B3digo Java, = - assim este =C3=A9 o melhor que pode ser feito sem util= izar JNI. - - - - - Colunas de identidade e sequencias - - Para bancos de dados que suportam colunas de identidad= e (DB2, MySQL, Sybase, = - MS SQL), voc=C3=AA pode utilizar uma gera=C3=A7=C3=A3o= de chave identity. = - Para bancos de dados que suportam sequencias (DB2, Ora= cle, PostgreSQL, Interbase, = - McKoi, SAP DB) voce pode utilizar a gera=C3=A7=C3=A3o = de chaves no estilo = - sequence. As duas estrat=C3=A9gias = requerem duas consultas SQL = - para inserir um novo objeto. = - - - - - person_id_sequence - -]]> - - - -]]> - = - - Para desenvolvimento multi-plataforma, a estrat=C3=A9g= ia native = - ir=C3=A1 escolher entre as estrat=C3=A9gias i identity, = - sequence e hilo,= dependendo das = - capacidades do banco de dados utilizado. - - - = - - Identificadores especificados - - Se voc=C3=AA quer que a aplica=C3=A7=C3=A3o especifiqu= e os identificadores = - (em vez do Hibernate ger=C3=A1-los) voc=C3=AA deve uti= lizar o gerador = - assigned. Este gerador especial ir= =C3=A1 utilizar o valor = - do identificador especificado para a propriedade de id= entifica=C3=A7=C3=A3o do objeto. = - Este gerador =C3=A9 usado quando a chave primaria =C3= =A9 a chave natural em vez de uma = - surrogate key. Este =C3=A9 o comportamento padr=C3=A3o= se voc=C3=AA n=C3=A3o especificar = - um elemento <generator>. = - - = - - Escolher o gerador assigned faz com= que o Hibernate = - utilize unsaved-value=3D"undefined"= , for=C3=A7ando o Hibernate = - ir at=C3=A9 o banco de dados para determinar se uma in= st=C3=A2ncia est=C3=A1 transiente ou = - desasociada, a menos que haja uma vers=C3=A3o ou uma p= ropriedade timestamp, = - ou voc=C3=AA pode definir Interceptor.isUnsav= ed(). - - - - - Chaves prim=C3=A1rias geradas por triggers - - Apenas para sistemas legados (o Hibernate nao gera DDL= com triggers). - - - - - socialSecurityNumber - -]]> - - - No exemplo acima, h=C3=A1 uma =C3=BAnica propriedade c= om valor nomeada = - socialSecurityNumber definida pela= classe, = - uma chave natural, e uma surrogate key nomeada = - person_id cujo valor =C3=A9 gerado = pro uma trigger. - - = - - - - - - composite-id - - - node=3D"element-name|." - - - - ...... -]]> - - - Para tabelas com uma chave composta, voc=C3=AA pode mapear= m=C3=BAltiplas propriedades = - da classe como propriedades de identifica=C3=A7=C3=A3o. O = elemento = - <composite-id> aceita o mapeament= o da propriedade = - <key-property> e mapeamentos = - <key-many-to-one>como elements fi= lhos. - - = - - - -]]> - - - Sua classe persistente precisa sobre = escrever = - equals() e hashCode() para implementar = - identificadores compostos igualmente. E precisa tamb=C3=A9= m implementar = - Serializable. - - - - Infelizmente, esta solu=C3=A7=C3=A3o para um identificador= composto significa que um objeto = - persistente =C3=A9 seu pr=C3=B3prio identificador. N=C3=A3= o h=C3=A1 outro "handle" que o pr=C3=B3prio objeto. = - Voc=C3=AA mesmo precisa instanciar uma inst=C3=A2ncia de o= utra classe persistente e preencher = - suas propriedades de identifica=C3=A7=C3=A3o antes que voc= =C3=AA possa dar um load() - para o estado persistente associado com uma chave composta= . Nos chamamos esta = - solu=C3=A7=C3=A3o de identificador composto embe= dded e n=C3=A3o aconselhamos = - para aplica=C3=A7=C3=B5es s=C3=A9rias. = - - = - - Uma segunda solu=C3=A7=C3=A3o =C3=A9 o que podemos chamar = de identificador composto = - mapped quando a propriedades de ident= ifica=C3=A7=C3=A3o nomeadas dentro do = - elemento <composite-id> est=C3=A3= o duplicadas tando na classe = - persistente como em uma classe de identifica=C3=A7=C3=A3o = separada. = - - = - - - -]]> - - - No exemplo, ambas as classes de identifica=C3=A7=C3=A3o co= mpostas, MedicareId, = - e a pr=C3=B3pria classe entidade tem propriedades nomeadas= medicareNumber = - e dependent. A classe identificadora pr= ecisa sobrepor = - equals() e hashCode() e implementar = - Serializable. A desvantagem desta solu= =C3=A7=C3=A3o =C3=A9 obvia =E2=80=93 = - duplica=C3=A7=C3=A3o de c=C3=B3digo. - - = - - Os seguintes atributos =C3=A3o utilizados para especificar= o mapeamento de = - um identificador composto: - - - - - - mapped mapped (opcional, valor = default false - ): indica que um identificar composto ma= peado =C3=A9 usado, e que as = - propriedades de mapeamento contidas refere-se tant= o a classe entidade e = - a classe de identifica=C3=A7=C3=A3o composta. - - - - - class (opcional, mas requerida = para um identificar composto = - mapeado): A classe usada como um identificador com= posto. = - - - - - - N=C3=B3s iremos descrever uma terceira e as vezes mais con= veniente solu=C3=A7=C3=A3o, onde o = - identificador composto =C3=A9 implementado como uma classe= componente na = - . Os atributos d= escritos abaixo aplicam-se = - apenas para esta solu=C3=A7=C3=A3o: - - - - - - name (opcional, requerida para = esta solu=C3=A7=C3=A3o): Uma = - propriedade do tipo componente que armazena o iden= tificador composto = - (veja cap=C3=ADtulo 9) = - - - - - access (opcional - valor defaul= t property): = - A estart=C3=A9gia Hibernate que deve ser utilizada= para acessar o valor da propriedade. - - - - - class (opcional - valor default= para o tipo de propriedade = - determiando por reflex=C3=A3o) : A classe componen= te utilizada como um identificador = - composto (veja a pr=C3=B3xima sess=C3=A3o). - - - - = - - Esta terceira solu=C3=A7=C3=A3o, um componente d= e identifica=C3=A7=C3=A3o, =C3=A9 o que n=C3=B3s = - recomendamos para a maioria das aplica=C3=A7=C3=B5es. - - = - - = - - discriminator - - - O elemento <discriminator> =C3= =A9 necess=C3=A1rio para persist=C3=AAncia = - polim=C3=B3rfica utilizando a estrat=C3=A9gia de mapeament= o table-per-class-hierarchy e declara = - uma coluna discriminadora da tabela. A coluna discriminado= ra contem valores de marca=C3=A7=C3=A3o = - que dizem a camada de persist=C3=AAncia qual subclasse ins= tanciar para uma linha particular. = - Um restrito conjunto de tipos que podem ser utilizados: string, = - character, integer, = byte, = - short, boolean, = - yes_no, true_false. - - = - - - - - - - - - ]]> - - - - column (opcional - valor de= fault class) = - o nome da coluna discriminadora - - - - - type (opcional - valor defa= ult string) = - o nome que indica o tipo Hibernate - - = - - - force (opcional - valor def= ault false) = - "for=C3=A7a" o Hibernate a especificar valores= discriminadores permitidos mesmo = - quando recuperando todas as instancias da clas= se root. - - = - - - insert (opcional - valor de= fault para true) = - sete isto para false se sua= coluna discriminadora =C3=A9 tamb=C3=A9m = - parte do identificador composto mapeado. (Diz = ao Hibernate para n=C3=A3o incluir a = - coluna em comandos SQL INSERTs). = - - - - - formula (opcional) uma expr= ess=C3=A3o SQL arbitraria que =C3=A9 e - xecutada quando um tipo tem que ser avaliado. = Permite discrimina=C3=A7=C3=A3o baseada = - em conte=C3=BAdo. - - - - - - - Valores atuais de uma coluna discriminada s=C3=A3o especif= icados pelo atributo = - discriminator-value da <cla= ss> = - e elementos da <subclass>. - - = - - O atributo force =C3=A9 util (apenas) = em tabelas contendo linhas com = - valores discriminadores "extras" que n=C3=A3o est=C3=A3o m= apeados para uma classe persistente. = - Este n=C3=A3o =C3=A9 geralmente o caso. - - - - Usando o atributo formula voce pode dec= larar uma express=C3=A3o SQL = - arbitr=C3=A1ria que sera utilizada para avaliar o tipo de = uma linha : - - - ]]> - - - - - version (optional) - = - - O elemento <version> =C3=A9 opcio= nal e indica que a tabela = - possui dados versionados. Isto =C3=A9 particularmente =C3= =BAtil se voc=C3=AA planeja utilizar = - transa=C3=A7=C3=B5es longas (veja aba= ixo): - - = - - - - - - - - - - - ]]> - - - - column (opcional - default = a a propriedade name): O nome da = - coluna mantendo o numero da vers=C3=A3o = - - = - - - name: O nome da propriedade= da classe persistente. - - - - - type (opcional - valor defa= ult para integer): = - O tipo do numero da vers=C3=A3o - - = - - - access (opcional - valor de= fault property): = - A estrat=C3=A9gia Hibernate que deve ser usada= para acessar o valor da propriedade. - - - - - unsaved-value (opcional = =E2=80=93 valor default para undefined - ): Um valor para a propriedade vers= =C3=A3o que indica que uma instancia =C3=A9 = - uma nova instanciada (unsaved), distinguindo d= e instancias desconectadas que foram = - salvas ou carregadas em sess=C3=B5es anteriore= s. ((undefined especifica = - que o valor da propriedade de identifica=C3=A7= =C3=A3o deve ser utilizado). - - - - - generated (optional - defau= lts to never): - Specifies that this version property value is = actually generated by the database. - See the discussion of generated properties. - generated (opcional - valor= default never): = - Especifica que valor para a propriedade vers= =C3=A3o =C3=A9 na verdade gerado pelo banco de = - dados. Veja a discuss=C3=A3o da Se=C3=A7=C3=A3= o = - generated = properties. = - - - - - insert (opcional - valor de= fault para true): = - Especifica se a coluna de vers=C3=A3o deve ser= inclu=C3=ADda no comando SQL de insert. = - Pode ser configurado como false se a coluna do banco de dados = - est=C3=A1 definida com um valor default de 0. - - - - - = - - N=C3=BAmeros de vers=C3=A3o podem ser dos tipos Hibernate = long, = - integer, short, timestamp ou - calendar. - - = - - A vers=C3=A3o de uma propriedade timestamp nunca deve ser = nula para uma instancia = - desconectada, assim o Hibernate ir=C3=A1 identificar qualq= uer inst=C3=A2ncia com uma vers=C3=A3o = - nula ou timestamp como transiente, n=C3=A3o importando qua= l estrat=C3=A9gia para foi = - especificada para unsaved-value. Declarando uma vers=C3=A3o = - nula ou a propriedade timestamp =C3=A9 um caminho f=C3=A1c= il para tratar problemas com = - reconex=C3=B5es transitivas no Hibernate, especialmente = =C3=BAteis para pessoas utilizando = - identificadores assinaldados ou chaves compostas! - - - = - - timestamp (optional) - - - O elemento opcional <timestamp> i= ndica que uma tabela cont=C3=A9m = - dados timestamped. Isso tem por objetivo dar uma alternati= va para versionamento. Timestamps = - s=C3=A3o por natureza uma implementa=C3=A7=C3=A3o menos se= gura do locking otimista. Entretanto, algumas = - vezes a aplica=C3=A7=C3=A3o pode usar timestamps em outros= caminhos. - - = - - - - - - - - - = - ]]> - - - - column (opcional - valor de= fault para a propriedade name): = - O nome da coluna que mantem o timestamp. - - = - - - name: O nome da propriedade= no estilo JavaBeans do = - tipo Date ou Times= tamp da classe = - persistente Java. - - - - - access (opcional - valor de= fault para property): = - A estretagia Hibernate que deve ser utilizada = para acessar o valor da propriedade. - - - - - unsaved-value (opcional - v= alor default null): = - Uma propriedade para a vers=C3=A3o de que indi= ca que uma inst=C3=A2ncia =C3=A9 uma nova instanciada = - (unsaved), distinguindo-a de instancias descon= ectadas que foram salvas ou carregadas = - em sess=C3=B5es previas. (undefined especifica que um valor de = - propriedade de identifica=C3=A7=C3=A3o deve se= r utilizado) - - - - - source (opcional - valor d= efault para vm): = - De onde o Hibernate deve recuperar o valor tim= estamp? Do banco de dados ou da JVM = - corrente? Timestamps baseados em banco de dado= s levam a um overhead porque o = - Hibernate precisa acessar o banco de dados par= a determinar o "pr=C3=B3ximo valor", mas =C3=A9 = - mais seguro para uso em ambientes de "cluster"= . Observe tamb=C3=A9m, que nem todos = - Dialects suportam a recuper= a=C3=A7=C3=A3o do timestamp corrente do banco = - de dados, enquando outros podem n=C3=A3o ser s= eguros para utiliza=C3=A7=C3=A3o em bloqueios = - pela falta de precis=C3=A3o (Oracle 8 por exem= plo) - - - - - generated (opcional - valor= default never): = - Especifica que o valor da propriedade timestam= p =C3=A9 gerado pelo banco de dados. = - Veja a discuss=C3=A3o generated properties. = - - - - - = - - Observe que <timestamp> =C3=A9 eq= uivalente a = - <version type=3D"timestamp">. E = - <timestamp source=3D"db"> =C3=A9 = equivalente a = - <version type=3D"dbtimestamp">. - - - - - - property - - - O elemento <property> declara uma= propriedade = - persistente de uma classe, no estilo JavaBean. = - - = - - - - - - - - - - - - - - - - - = - ]]> - - - - name: o nome da propriedade= , iniciando com letra min=C3=BAscula. - - = - - - column (opcional - default = para a propriedade name): o nome = - da coluna mapeada do banco de dados, Isto pode= tamb=C3=A9m ser especificado pelo(s) = - elemento(s) <column> = aninhados. - - - - - - type (opcional): um nome qu= e indica o tipo Hibernate. - - - - - update, insert (opcional - = valor default true): - especifica que as colunas mapeadas devem ser i= ncluidas nas instru=C3=A7=C3=B5es SQL de = - UPDATE e/ou INSERT= . Setar ambas para to = - false permite uma propridad= e "derivada" pura cujo valor =C3=A9 = - inicializado de outra propriedade que mapeie a= mesma coluna(s) ou por uma trigger = - ou outra aplica=C3=A7=C3=A3o. - - - - - formula (opcional): uma ex= press=C3=A3o SQL que definie o valor para = - uma propriedade calculada= . Propriedades calculadas nao tem = - uma coluna de mapeamento para elas. - - - - - access (opcional =E2=80=93 = valor default property): = - A estrat=C3=A9gia que o Hibernate deve utiliza= r para acessar o valor da propriedade - - - - - lazy (opcional - valor defa= ult para false): = - Especifica que esta propriedade deve ser trazi= da de forma "lazy" quando a = - instancia da vari=C3=A1vel =C3=A9 acessada pel= a primeira vez (requer instrumenta=C3=A7=C3=A3o = - bytecode em tempo de cria=C3=A7=C3=A3o). - - - - - unique (opcional): Habilita= a gera=C3=A7=C3=A3o de DDL de uma = - unica constraint para as colunas. Assim, permi= te que isto seja o = - alvo de uma property-ref. - - - - - not-null (opcional): Habili= ta a gera=C3=A7=C3=A3o de DDL de uma = - constraint de nulidade para as colunas. - - - - - optimistic-lock (opcional -= valor default true): - Especifica se mudan=C3=A7as para esta propried= ade requerem ou n=C3=A3o bloqueio otimista. = - Em outras palavras, determina se um incremento= de vers=C3=A3o deve ocorrer quando = - esta propriedade est=C3=A1 suja. - - - - - generated (opcional - valor= default never): = - Especifica que o valor da propriedade =C3=A9 n= a verdade gerado pelo banco de dados. - Veja a discuss=C3=A3o da se=C3=A7=C3=A3o = - generated = properties. - - - - - - - typename pode ser: - - - - - - The name of a Hibernate basic type (eg. i= nteger, string, character, - date, timestamp, float, binary, serializable, obje= ct, blob). - O nome do tipo basico do Hibernate (ex., = integer, string, character, - date, timestamp, float, binary, serializable, obje= ct, blob). - - - - - O nome da classe Java com um tipo b=C3=A1sico defa= ult (ex. int, float, - char, java.lang.String, java.util.Date, java.lang.= Integer, java.sql.Clob). - - - - - O nome da classe Java serializable - - - - - O nome da classe de um tipo customizado (ex. com.illflow.type.MyCustomType). - - - - - - Se voc=C3=AA n=C3=A3o especificar um tipo, o Hibernate ira= utilizar reflex=C3=A3o sobre a = - propriedade nomeada para ter uma id=C3=A9ia do tipo Hibern= ate correto. O Hibernate ira = - tentar interpretar o nome da classe retornada, usando as r= egras 2, 3 e 4 nesta ordem. = - Entretanto, isto n=C3=A3o =C3=A9 sempre suficiente Em cert= os casos, voc=C3=AA ainda ir=C3=A1 necessitar - do atributo type. (Por exemplo, para di= stinguir entre = - Hibernate.DATE ou Hibernate.TI= MESTAMP, = - ou para espcificar uma tipo ciustomizado.) - - = - - O atributo access permite voce controla= r como o Hibernate ir=C3=A1 = - acessar a propriedade em tempo de execu=C3=A7=C3=A3o. Por = default, o Hibernate ir=C3=A1 chamar os = - m=C3=A9todos get/set da propriedades. Se voce especificar = access=3D"field", = - o Hibernate ira bipassar os metodos get/set, acessnado o c= ampo diretamente, = - usando reflex=C3=A3o. Voc epode especificar sua pr=C3=B3pr= ia estrat=C3=A9gia para acesso da = - propriedade criando uma classe que implemente a interface = - org.hibernate.property.PropertyAccessor. - - - - Um recurso especialmente poderoso =C3=A9 o de propriedades= derivadas. Estas propriedades = - s=C3=A3o por defini=C3=A7=C3=A3o read-only, e o valor da p= ropriedade =C3=A9 calculado em tempo de execu=C3=A7=C3=A3o. = - Voc=C3=AA declara este calculo como uma express=C3=A3o SQL= , que traduz para clausula = - SELECT de uma subquery daquery SQL que = carrega a instancia: = - - - ]]> - - - Observe que voc=C3=AA pode referenciar as entidades da pr= =C3=B3pria tabela, = - atrav=C3=A9s da n=C3=A3o declara=C3=A7=C3=A3o de um alias = para uma coluna particular ( - customerId no exemplo dado). Observe ta= mbem que voce pode usar o = - mapeamento de elemento aninhado <formula>, se voc=C3=AA n=C3=A3o = - gostar de usar o atributo. - - - - - - many-to-one - - - Uma associa=C3=A7=C3=A3o ordin=C3=A1ria para outra classe = persistente =C3=A9 declarada usando o = - elemento many-to-one. O modelo relacion= al =C3=A9 uma = - associa=C3=A7=C3=A3o many-to-one: a uma chave estrangeira = de uma tabela referenciando - a chave primaria da tabela destino. - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - name: O nome da propriedade. - = - = - - - column (opcional): O nome d= a coluna foreign key. Isto = - pode tamb=C3=A9m ser especificado atrav=C3=A9s= de elementos aninhados = - <column>. - - - - - class (opcional =E2=80=93 d= efault para o tipo de propriedade = - determinado pela reflex=C3=A3o). O nome da cla= sse associada. = - - - - - cascade (opcional): Especif= ica quais opera=C3=A7=C3=B5es dever = - ser em cascata do objeto pai para o objeto ass= ociado. = - = - - - - fetch (opcional - default p= ara select): = - Escolhe entre recupera=C3=A7=C3=A3o outer-join= ou recupera=C3=A7=C3=A3o seq=C3=BCencial. - = - - - - update, insert (opcional - = valor default true): - especifica que as colunas mapeadas dever ser i= ncluidas em instru=C3=A7=C3=B5es SQL de = - UPDATE e/ou INSERT= . Setando ambas para = - false voc=C3=AA permite uma= associa=C3=A7=C3=A3o "derivada" pura cujos valores = - s=C3=A3o inicializados de algumas outras propr= iedades que mapeiam a mesma coluna ou = - por uma trigger ou outra aplica=C3=A7=C3=A3o. = - = - - - - property-ref: (opcional) O = nome da propriedade da classe associada = - que faz a jun=C3=A7=C3=A3o desta foreign key. = Se n=C3=A3o especificada, a chave primaria da = - classe associada ser=C3=A1 utilizada. = - = - = - - - access (opcional - valor de= fault property): A = - estrategia que o Hibernate deve utilizar para = acessar o valor da propriedade. - - - - - unique (opcional): Habilita= a gera=C3=A7=C3=A3o DDL de uma constraint = - unique para a coluna foreign-key. Alem disso, = permite ser o alvo de uma = - property-ref. Isso torna a = associa=C3=A7=C3=A3o multipla = - efetivamente um para um. = - - - - - not-null (opcional): Habili= ta a gera=C3=A7=C3=A3o DDL de uma constraint de = - nulidade para as foreign keys. - - - - - optimistic-lock (opcional -= valor default true): = - Especifica se mudan=C3=A7as desta propriedade = requerem ou n=C3=A3o travamento otimista. = - Em outras palavras, determina se um incremento= de vers=C3=A3o deve ocorrer quando = - esta propriedade est=C3=A1 suja. - - - - - lazy(opcional =E2=80=93 val= or default proxy): = - Por default, associa=C3=A7=C3=B5es de ponto un= ico s=C3=A3o envoltas em um proxie. = - lazy=3D"no-proxy" especific= a que a propriedade deve ser = - trazida de forma tardia quando a instancia da = vari=C3=A1vel =C3=A9 acessada pela = - primeira vez (requer instrumenta=C3=A7=C3=A3o = bytecode em tempo de cria=C3=A7=C3=A3o) = - lazy=3D"false" especifica q= ue a associa=C3=A7=C3=A3o ser=C3=A1 = - sempre recuperada fortemente. = - - - - - not-found (opcional - valor= default exception): = - Especifica como as foreign keys que referencia= m linhas ausentes ser=C3=A3o tratadas: - ignore ir=C3=A1 tratar a li= nha ausente como ama associa=C3=A7=C3=A7ao de null - - - - - entity-name (opcional): O n= ome da entidade da classe associada. = - = - - - - - formula (optional): Uma exp= ress=C3=A3o SQL que define um valor - para um foreign key computed. - - - - - - Setar o valor do atributo cascade para= qualquer valor = - significativo diferente de none ir=C3= =A1 propagar certas opera=C3=A7=C3=B5es = - ao objeto associado. Os valores significativos s=C3=A3o os= nomes das opera=C3=A7=C3=B5es b=C3=A1sicas = - do Hibernate, persist, merge, delete, save-update= , evict, replicate, lock, - refresh, assim como os valores especiais delete-orphan = - e all e combina=C3=A7=C3=B5es de nomes = de opera=C3=A7=C3=B5es separadas por v=C3=ADrgula, = - como por exemplo, cascade=3D"persist,merge,evict"= ou - cascade=3D"all,delete-orphan". Veja a s= e=C3=A7=C3=A3o = - para uma explic= a=C3=A7=C3=A3o completa. Note que = - associa=C3=A7=C3=B5es valoradas simples (associa=C3=A7=C3= =B5es muitos-pra-um, e um-pra-um) n=C3=A3o suportam = - orphan delete. - - = - - Uma t=C3=ADpica declara=C3=A7=C3=A3o muitos-pra-u= m se parece com esta: - - - ]]> - = - - O atributo property-ref deve apenas ser= usado para mapear dados = - legados onde uma chave estrangeira se referencia a uma cha= ve exclusiva da tabela = - associada que n=C3=A3o seja =C3=A0 chave prim=C3=A1ria. Es= te =C3=A9 um modelo relacional desagrad=C3=A1vel. = - Por exemplo, suponha que a classe Product tenha um n=C3=BAmero = - seq=C3=BCencial exclusivo, que n=C3=A3o =C3=A9 a chave pri= m=C3=A1ria. (O atributo unique = - controla a gera=C3=A7=C3=A3o de DDL do Hibernate com a fer= ramenta SchemaExport.) - - = - ]]> - = - - Ent=C3=A3o o mapeamento para OrderItem = poderia usar: - - = - ]]> - = - - Por=C3=A9m, isto obviamente n=C3=A3o =C3=A9 indicado, nunc= a. - - = - - Se a chave exclusiva referenciada engloba m=C3=BAltiplas p= ropriedades da entidade associada, = - voc=C3=AA deve mapear as propriedades referenciadas dentro= de um elemento chamado = - <properties> - - - = - - Se a chave exclusiva referenciada =C3=A9 a propriedade de um = componente, voc=C3=AA pode especificar = - um caminho para a propriedade. = - - = - ]]> = - = - - - - one-to-one (um-pra-um) - - - Uma associa=C3=A7=C3=A3o um-pra-um para outra classe persi= stente =C3=A9 declarada usando = - um elemento one-to-one . - - = - - - - - - - - - - - - - - ]]> - - - - name: O nome da propriedade. - = - = - - - class (opcional =E2=80=93 d= efault para o tipo da propriedade = - definido via reflection): O nome da classe ass= ociada. - = - - - - cascade (opcional): Especif= ica qual opera=C3=A7=C3=A3o deve = - ser cascateada do objeto pai para o objeto ass= ociado. - - - - - constrained (opcional): Esp= ecifica que uma chave estrangeira = - constraint na chave prim=C3=A1ria da tabela ma= peada referencia a tabela da classe = - associada, Esta op=C3=A7=C3=A3o afeta a ordem = em queh save() e - delete() s=C3=A3o cascatead= as, e determina se a associa=C3=A7=C3=A3o = - pode ser substitu=C3=ADda (isto tamb=C3=A9m = =C3=A9 usado pela ferramenta schema export). - = - - - - fetch ((opcional =E2=80=93 = valor default select): = - Escolhe entre outer-join fetching ou sequentia= l select fetching. - = - - - - property-ref(opcional): O n= ome da propriedade da classe associada = - que =C3=A9 ligada a chave prim=C3=A1ria desta = classe. Se n=C3=A3o for especificada, a chave prim=C3=A1ria = - da classe associada =C3=A9 utilizada. - = - = - - - access (opcional - valor de= fault padr=C3=A3o property): = - A estrat=C3=A9gia que o Hibernate pode usar pa= ra acessar o valor da propriedade. - - - - - formula (opcional): Quase t= odas associa=C3=A7=C3=B5es um-pra-um mapeiam = - para a chave prim=C3=A1ria da entidade dona. N= o caso raro, que n=C3=A3o =C3=A9 o caso, voc=C3=AA = - pode especificar uma outra coluna, colunas ou = express=C3=B5es para juntar utilizando = - uma formula SQL. (Veja org.hibernate.= test.onetooneformula = - para exemplo). - - - - - lazy (opcional =E2=80=93 va= lor default proxy): = - Por default, associa=C3=A7=C3=B5es single poin= t s=C3=A3o proxied. lazy=3D"no-proxy" = - especifica que a propriedade deve ser fetched = lazily quando o atributo =C3=A9 acessado = - pela primeira vez (requer build-time bytecode = instrumentation). = - lazy=3D"false" especifica q= ue a associa=C3=A7=C3=A3o vai sempre ser = - avidamente fetched. Note que se constrained=3D"false", = - proxing =C3=A9 imposs=C3=ADvel e o Hibernate v= ai =C3=A1vido fetch a associa=C3=A7=C3=A3o! - - - - - entity-name (opcional): O n= ome da entidade da classe associada. - = - - - - = - - Existem duas variedades de associa=C3=A7=C3=B5es um-pra-um: - - - - associa=C3=A7=C3=B5es de chave prim=C3=A1ria - - - associa=C3=A7=C3=B5es de chave estrangeira exclusiva - - - = - - Associa=C3=A7=C3=B5es de chave prim=C3=A1ria n=C3=A3o nece= ssitam de uma coluna extra de tabela; se duas = - linhas s=C3=A3o relacionadas pela associa=C3=A7=C3=A3o ent= =C3=A3o as duas linhas da tabela dividem a mesmo = - valor da chave prim=C3=A1ria. Assim, se voc=C3=AA quer que= dois objetos sejam relacionados por = - uma associa=C3=A7=C3=A3o de chave prim=C3=A1ria, voc=C3=AA= deve ter certeza que eles s=C3=A3o assinados com o = - mesmo valor identificador! - - = - - Para uma associa=C3=A7=C3=A3o de chave prim=C3=A1ria, adic= ione os seguintes mapeamentos em = - Employee e Person, r= espectivamente. - - - ]]> - ]]> - - - Agora n=C3=B3s devemos assegurar que as chaves prim=C3=A1r= ias de linhas relacionadas nas = - tabelas PERSON e EMPLOYEE s=C3=A3o iguais. N=C3=B3s usamos= uma estrat=C3=A9gia especial de gera=C3=A7=C3=A3o = - de identificador do Hibernate chamada foreign: - - - - - - employee - - - ... - -]]> - - - Uma nova inst=C3=A2ncia de Person salva= recentemente =C3=A9 ent=C3=A3o assinada = - com o mesmo valor da chave prim=C3=A1ria da inst=C3=A2ncia= de employee referenciada = - com a propriedade employee daquela Person. - - - - Alternativamente, uma chave estrangeira com uma unique con= straint, de = - Employee para Person= , pode ser expressa como: - - = - ]]> - = - - E esta associa=C3=A7=C3=A3o pode ser feita de forma bi-dir= ecional adicionando o seguinte = - no mapeamento de Person: - - = - ]]> - - - - - natural-id - - - - - ...... -]]> - - - Embora n=C3=B3s recomendemos o uso de surrogate keys como = chaves prim=C3=A1rias, voc=C3=AA deve = - ainda identificar chaves naturais para todas as entidades.= Uma chave natural =C3=A9 = - uma propriedade ou combina=C3=A7=C3=A3o de propriedades qu= e =C3=A9 exclusiva e n=C3=A3o nula. Se n=C3=A3o = - pude ser modificada, melhor ainda. Mapeie as propriedades = da chave natural dentro do = - elemento <natural-id>. O Hibernat= e ir=C3=A1 gerar a chave = - exclusiva necess=C3=A1ria e as constraints de nullability = , e seu mapeamento ser=C3=A1 = - apropriadamente auto documentado. - - = - - N=C3=B3s recomendamos com enfase que voc=C3=AA implemente = equals() e = - hashCode() para comparar as propriedade= s da chave natural da = - entidade. - - - - Este mapeamento n=C3=A3o tem o objetivo de uso com entidad= es com natural chaves prim=C3=A1rias. - - - - - - mutable mutable (opcional, val= or defaultfalse): = - Por default, propriedades naturais identificadoras= s=C3=A3o consideradas imut=C3=A1veis (constante). - - - - = - - = - - componente, componente din=C3=A2mico - - - O elemento<component> mapeia prop= riedades de um = - objeto filho para colunas da tabela de uma classe pai. Com= ponentes podem, = - um ap=C3=B3s o outro, declarar suas pr=C3=B3prias propried= ades, componentes ou cole=C3=A7=C3=B5es. = - Veja "Components" abaixo. - - - - - - - - - - - - - = - - = - - - ........ -]]> - - - - name: O nome da propriedade. - = - = - - - class (opcional =E2=80=93 v= alor default para o tipo de = - propriedade determinada por reflection): O nom= e da classe (filha) do = - componente. - = - - - - insert: As colunas mapeadas= aparecem nos = - SQL de INSERTs? - = - = - - - update: As colunas mapeadas= aparecem nos = - SQL de UPDATEs? - = - = - - - access (opcional =E2=80=93 = valor default property): = - A estrat=C3=A9gia que o Hibernate pode usar pa= ra acessar o valor da propriedade. - - - - - lazy (opcional - valor defa= ult false): = - Especifica que este componente deve ser fetche= d lazily quando o atributo for = - acessado pela primeira vez (requer build-time = bytecode instrumentation). - - - - - optimistic-lock (opcion= al =E2=80=93 valor default true): = - Especifica que atualiza=C3=A7=C3=B5es para= este componente requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o = - de um lock otimista. Em outras palavras, d= etermina se uma vers=C3=A3o de incremento deve = - ocorrer quando esta propriedade estiver mo= dificada. - - - - - unique (opcional =E2=80= =93 valor default false): = - Especifica que existe uma unique constrain= t em todas as colunas mapeadas do = - componente. - - - - - - - A tag filha <property> acrescenta= a propriedade - de mapeamento da classe filha para colunas de uma tabela. - - - - O elemento <component> permite um= sub-elemento = - <parent> mapeie uma propriedade d= a classe do componente = - como uma referencia de volta para a entidade que o cont=C3= =A9m. - - - - O elemento <dynamic-component> p= ermite que um = - Map possa ser mapeado como um component= e onde os nomes das = - propriedades referem-se para as chaves no mapa, veja = - . - - = - - - - propriedades - - - O elemento <properties> permite a= defini=C3=A7=C3=A3o de um grupo = - com nome, l=C3=B3gico de propriedades de uma classe. O uso= mais importante do construtor = - =C3=A9 que este permite uma combina=C3=A7=C3=A3o de propri= edades para ser o objetivo de uma = - property-ref. =C3=89 tamb=C3=A9m um mod= o conveninente para definir uma = - unique constraint de m=C3=BAltiplas colunas. - - - - - - - - - - = - - = - - - ........ -]]> - - - - name:: O nome l=C3=B3gico d= o agrupamento =E2=80=93 = - n=C3=A3o =C3=A9 o nome a= tual de propriedade. - = - = - - - insert: As colunas mapeadas= aparecem nos = - SQL de INSERTs? - = - = - - - update: As colunas mapeadas= aparecem nos = - SQL de UPDATEs? - = - = - - - optimistic-lock (opcion= al =E2=80=93 valor default true): = - Especifica que atualiza=C3=A7=C3=B5es para= estes componentes requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o de um - lock otimista. Em outras palavras, determi= na se uma vers=C3=A3o de incremento deve ocorrer = - quando estas propriedades estiverem modifi= cadas. - - - - - unique (opcional =E2=80= =93 valor defautl false): = - Especifica que uma unique constraint exist= e em todas as colunas mapeadas do componente. - - - - - = - - Por exemplo, se n=C3=B3s temos o seguinte mapeamento de <properties>: - - = - - - ... - - - - - -]]> - - - Ent=C3=A3o n=C3=B3s podemos ter uma associa=C3=A7=C3=A3o = de dados herdados que referem a esta chave = - exclusiva da tabela Person, ao inv=C3= =A9s de se referirem a chave = - prim=C3=A1ria: - - - - - - -]]> - = - - N=C3=B3s n=C3=A3o recomendamos o uso deste tipo de coisa f= ora do contexto de mapeamento de = - dados herdados. - - = - - - - subclass (subclasse) - - - Finalmente, a persist=C3=AAncia polim=C3=B3rfica requer a = declara=C3=A7=C3=A3o de cada subclasse = - da classe de persist=C3=AAncia raiz. Para a estrat=C3=A9gi= a de mapeamento = - table-per-class-hierarchy, a declara=C3=A7=C3=A3o <subclass> - deve ser usada. = - - = - - - - - - - - - - - ..... -]]> - - - - name: O nome de classe com= pletamente qualificada da subclasse. = - = - = - - - discriminator-value (opcion= al =E2=80=93 valor default o nome da classe): = - Um valor que distingue subclasses individuais. - = - - - - proxy (opcional): Especific= a a classe ou interface que = - usar=C3=A1 os proxies de inicializa=C3=A7=C3= =A3o atrasada. - = - - - - lazy (opcional, valor defau= lt true): = - Configurar lazy=3D"false" d= esabilitar=C3=A1 o uso de = - inicializa=C3=A7=C3=A3o atrasada. - - = - - - - Cada subclasse deve declarar suas pr=C3=B3prias propriedad= es persistentes e subclasses. = - As propriedades <version> e <id> = - s=C3=A3o configuradas para serem herdades da classe raiz. = Cada subclasse numa hierarquia = - deve definir um =C3=BAnico discriminator-value. Se nenhum for = - especificado, o nome da classe Java completamente qualific= ada ser=C3=A1 usada. - - = - - Para informa=C3=A7=C3=B5es sobre mapeamento de heran=C3=A7= as, veja o . - - - - - - joined-subclass - - - Alternativamente, cada subclasse pode ser mapeada para sua= pr=C3=B3pria tabela = - (Estrat=C3=A9gia de mapeamento table-per-subclass). O esta= do herdado =C3=A9 devolvido = - por associa=C3=A7=C3=A3o com a tabela da superclasse. N=C3= =B3s usamos o elemento = - <joined-subclass>. - - - - - - - - - - - - - - - ..... -]]> - - - - name: O nome da classe comp= letamente qualificada da = - subclasse. - = - = - - - table: O nome da tabela da = subclasse. - = - = - - - proxy (opcional): Especific= a a classe ou interface = - para usar os proxies de recupera=C3=A7=C3=A3o = atrasada. - = - - - - lazy (opcional, valor defau= lt true): = - Fixanr lazy=3D"false" desab= ilita o uso recupera=C3=A7=C3=A3o = - atrasada. - - = - - - - - A coluna discriminator requerida para esta estrat=C3=A9gia= de mapeamento. Por=C3=A9m, = - cada subclasse deve declarar uma coluna de tabela com o id= entificador do objeto = - usando o elemento <key>. O mapeam= ento no in=C3=ADcio do = - cap=C3=ADtulo poderia ser re-escrito assim: - - = - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - Para informa=C3=A7=C3=B5es de mapeamentos de heran=C3=A7a= , veja . - - - - - - union-subclass - - - Uma terceira op=C3=A7=C3=A3o =C3=A9 mapear para tabelas ape= nas as classes concretas de uma = - hierarquia de heran=C3=A7as, (a estrat=C3=A9gia table-per-c= oncrete-class) onde cada tabela = - define todos os estados persistentes da classe, incluindo e= stados herdados. = - No Hibernate, n=C3=A3o =C3=A9 absolutamente necess=C3=A1rio= mapear explicitamente como hierarquia = - de heran=C3=A7as. Voc=C3=AA pode simplesmente mapear cada c= lasse com uma declara=C3=A7=C3=A3o = - <class> separada. Por=C3=A9m, se v= oc=C3=AA deseja usar associa=C3=A7=C3=B5es = - polim=C3=B3rficas (por exemplo: uma associa=C3=A7=C3=A3o pa= ra a superclasse de sua hierarquia), = - voc=C3=AA precisa usar o mapeamento <union-subc= lass>. - - - - - - - - - - - - - - ..... -]]> - - - - name: O nome da subclasse c= ompletamente qualificada. - = - = - - - table: O nome da tabela da = subclasse. - = - = - - - proxy (optional): Specifies= a class or interface to use = - for lazy initializing proxies. - = - proxy (opcional): Especific= a a classe ou interface para usar = - os proxies de recupera=C3=A7=C3=A3o atrasada. - = - - - - lazy (optional, defaults to= true): Setting = - lazy=3D"false" disables the= use of lazy fetching. - lazy (opcional, valor defau= lt ptrue): = - Fixando lazy=3D"false" desa= bilita o uso da recupera=C3=A7=C3=A3o atrasada. - - - - - - - A coluna discriminat=C3=B5ria n=C3=A3o =C3=A9 requerida pa= ra esta estrat=C3=A9gia de mapeamento. - - - - - Para informa=C3=A7=C3=B5es sobre mapeamentos de heran=C3= =A7a, veja . - - - - - - join - - - Usando o elemento <join>>, =C3= =A9 poss=C3=ADvel mapear = - propriedades de uma classe para v=C3=A1rias tabelas. - - - - - - - - - - - - - = - - = - - ... -]]> - - - - - table: O nome da tabela ass= ociada. - - - - - schema (opcional): Sobrep= =C3=B5e o nome do esquema = - especificado pelo elemento raiz <h= ibernate-mapping>. - - - - - catalog (opcional): Sobrep= =C3=B5e o nome do cat=C3=A1logo - especificado pelo elemento raiz<hi= bernate-mapping>. - - - - - fetch(opcional =E2=80=93 va= lor default join): Se setado = - para join, o padr=C3=A3o, o= Hibernate ir=C3=A1 usar um inner join para = - restaurar um join definido = por uma classe ou suas subclasses e = - uma outer join para um join= definido por uma subclasse. = - Se setado para select, ent= =C3=A3o o Hibernate ir=C3=A1 usar uma sele=C3=A7=C3=A3o = - seq=C3=BCencial para um <join><= /literal> definida numa subclasse, que ir=C3=A1 = - ser emitido apenas se uma linha se concentrar = para representar uma inst=C3=A2ncia = - da subclasse. Inner joins ir=C3=A1 ainda ser u= sado para restaurar um = - <join> definido pela = classe e suas superclasses. - - - - - inverse (opcional =E2=80=93= valor default false): = - Se habilitado, o Hibernate n=C3=A3o ir=C3=A1 t= entar inserir ou atualizar as propriedades = - definidas por este join. - - - - - optional (opcional =E2=80= =93 valor default false): - Se habilitado, o Hibernate ir=C3=A1 inserir um= a linha apenas se as propriedades definidas = - por esta jun=C3=A7=C3=A3o n=C3=A3o forem nulas= e ir=C3=A1 sempre usar uma outer join para = - recuperar as propriedades. - - - - - - - Por exemplo, a informa=C3=A7=C3=A3o de endere=C3=A7o para = uma pessoa pode ser mapeada para uma = - tabela separada (enquanto preservando o valor da sem=C3=A2= ntica de tipos para = - todas as propriedades): = - - - - - ... - - - - - - - - ...]]> - - - Esta caracter=C3=ADstica =C3=A9 =C3=BAtil apenas para mode= los de dados legados, n=C3=B3s recomendamos = - menos tabelas do que classes e um modelo de dom=C3=ADnio b= em granulado. Por=C3=A9m, =C3=A9 = - =C3=BAtil para ficar trocando entre estrat=C3=A9gias de ma= peamento de heran=C3=A7a = - numa hierarquia simples, como explicado mais a frente. - - - - - - key - - - N=C3=B3s vimos que o elemento <key> surgiu algumas vezes - at=C3=A9 agora. Ele aparece em qualquer lugar que o elemen= to pai define uma jun=C3=A7=C3=A3o = - para a nova tabela, e define a chave estrangeira para a ta= bela associada, que = - referencia a chave prim=C3=A1ria da tabela original. = = - - - - - - - - - - - - ]]> - - - - . - column (opcional): O nome d= a coluna da chave estrangeira. = - Isto tamb=C3=A9m pode ser especificado por ani= nhamento de elemento(s) = - <column>. - - - - - on-delete (opcional, valor = default noaction): = - Especifica se a constraint da chave estrangeir= a no banco de dados esta - habilitada para cascade delete . - - - - - property-ref (opcional): Es= pecifica que a chave estrangeira = - se refere a colunas que n=C3=A3o s=C3=A3o chav= e prim=C3=A1ria da tabela original. = - (Util para base de dados legadas.) - - - - - not-null (opcional): Especi= fica que a coluna da chave = - estrangeira n=C3=A3o aceita valores nulos (ist= o =C3=A9 impl=C3=ADcito em qualquer momento = - que a chave estrangeira tamb=C3=A9m fizer part= e da chave prim=C3=A1ria). - - - - - update (optional): Specifie= s that the foreign key should never - be updated (this is implied whenever the forei= gn key is also part of the primary = - key). - update (opcional): Especifi= ca que a chave estrangeira nunca = - deve ser atualizada (isto =C3=A9 impl=C3=ADcit= o em qualquer momento que a chave estrangeira = - tamb=C3=A9m fizer parte da chave prim=C3=A1ria= ). - - - - - unique (opcional): Especif= ica que a chave estrangeira deve ter = - uma constraint unique (sto =C3=A9 impl=C3=ADci= to em qualquer momento que a chave estrangeira = - tamb=C3=A9m fizer parte da chave prim=C3=A1ria= ). - - - - - - - N=C3=B3s recomendamos que para sistemas que a performance = de delete seja importante, todas as = - chaves deve ser definida on-delete=3D"cascade", e o Hibernate ir=C3=A1 usar = - uma constraint a n=C3=ADvel de banco de dados ON = CASCADE DELETE, ao inv=C3=A9s = - de muitas instru=C3=A7=C3=B5es DELETE. = Esteja ciente que esta caracter=C3=ADstica =C3=A9 = - um atalho da estrat=C3=A9gia usual de optimistic locking d= o Hibernate para dados versionados. - - = - - Os atributos not-null e update= s=C3=A3o =C3=BAteis quando = - estamos mapeamos uma associa=C3=A7=C3=A3o unidirecional um= para muitos. Se voc=C3=AA mapear uma = - asocia=C3=A7=C3=A3o unidirecional um para muitos para uma = chave estrangeira non-nullable, voc=C3=AA = - deve declarar a coluna chave usando = - <key not-null=3D"true">. - - - - - - elementos column e formula - - Qualquer elemento de mapeamente que aceita um atributo column ir=C3=A1 = - aceitar alternativamente um subelemento <column= >. Da mesma forma, = - formula =C3=A9 uma alternativa para o at= ributo formula. = - - - ]]> - - SQL expression]]><= /programlisting> - = - - O atributo column e formula podem at=C3=A9 ser combinados - dentro da mesma propriedade ou associa=C3=A7=C3=A3o mapean= do para expressar, = - por exemplo, associa=C3=A7=C3=B5es ex=C3=B3ticas. - - - - - 'MAILING' -]]> - - = - = - - import - - - Suponha que a sua aplica=C3=A7=C3=A3o tem duas classes per= sistentes com o mesmo nome, e voc=C3=AA n=C3=A3o quer = - especificar o nome qualificado (do pacote) nas queries do = Hibernate. As Classes devem = - ser "importadas" explicitamente, de prefer=C3=AAncia conta= ndo com auto-import=3D"true". = - Voc=C3=AA pode at=C3=A9 importar classes e interfaces que = n=C3=A3o est=C3=A3o explicitamente mapeadas. - - = - ]]> - = - - - - - - ]]> - - - - class: O nome qualificado (= do pacote) de qualquer classe Java. - = - = - - - rename (opcional =E2=80=93 = valor default, o nome da classe n=C3=A3o = - qualificada): Um nome que pode ser usado numa = linguagem de consulta. - = - - - - = - - = - - any - = - - Existe mais um tipo de propriedade de mapeamento. O elemen= to de mapeamento = - <any> define uma associa=C3=A7=C3= =A3o polim=C3=B3rfica para classes de m=C3=BAltiplas tabelas. = - Este tipo de mapeamento sempre requer mais de uma coluna. = A primeira coluna possui o tipo da entidade = - associada. A outra coluna que ficou possui o identificador= . =C3=89 imposs=C3=ADvel especificar uma restri=C3=A7=C3=A3o = - de chave estrangeira para este tipo de associa=C3=A7=C3=A3= o, assim isto claramente n=C3=A3o =C3=A9 visto = - como um caminho usual para associa=C3=A7=C3=B5es (polim=C3= =B3rficas) de mapeamento. Voc=C3=AA deve usar este mapeamento - apenas em casos muito especiais (exemplo: audit logs, dado= s de sess=C3=A3o do usu=C3=A1rio, etc). - - - - - O atributo meta-type permite a aplica= =C3=A7=C3=A3o especificar um tipo adaptado = - que mapeia valores de colunas de banco de dados para clas= ses persistentes que tem propriedades = - identificadoras do tipo especificado atrav=C3=A9s do id-type. Voc=C3=AA deve especificar = - o mapeamento de valores do meta-type para nome de classes. - - - - - - - - -]]> - - - - - - - - - - - - - - ..... - - - ..... -]]> - - - - name: o nome da propriedade. - = - = - - - id-type: o tipo identificad= or. - = - = - - - meta-type (opcional =E2=80= =93 valor default string): = - Qualquer tipo que =C3=A9 permitido para um map= eamento discriminador. - = - = - - - cascade (opcional =E2=80=93= valor default none): = - o estilo do cascade. - = - = - - - access (opcional =E2=80=93 = valor default property): = - A estrat=C3=A9gia que o hibernate deve usar pa= ra acessar o valor da propriedade. - - - - - optimistic-lock (opcional -= valor defaulttrue): = - Especifica que as atualiza=C3=A7=C3=B5es para = esta propriedade requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o da = - trava otimista. Em outras palavras, define se = uma vers=C3=A3o de incremento deve ocorrer = - se esta propriedade est=C3=A1 modificada. - - - - - - - - - - - Tipos do Hibernate - - - Entidades e valores - - - Para entender o comportamento de v=C3=A1rios objetos em n= =C3=ADvel de linguagem de Java a = - respeito do servi=C3=A7o de persist=C3=AAncia, n=C3=B3s pr= ecisamos classific=C3=A1-los em dois grupos. - - - - Uma entidade existe independentement= e de qualquer outro = - objeto guardando refer=C3=AAncias para a entidade. Em cont= raste com o modelo usual de = - Java que um objeto n=C3=A3o referenciado =C3=A9 coletado p= elo garbage collector. Entidades = - devem ser explicitamente salvas ou deletada (exceto em ope= ra=C3=A7=C3=B5es de salvamento = - ou dele=C3=A7=C3=A3o que possam ser executada em cascata de uma entidade = - pai para seus filhos). Isto =C3=A9 diferente do modelo ODM= G de persist=C3=AAncia do objeto = - por acessibilidade =E2=80=93 e corresponde quase a como ob= jetos de aplica=C3=A7=C3=B5es s=C3=A3o = - geralmente usados em grandes sistemas. Entidades suportam = refer=C3=AAncias circulares = - e comuns. Eles podem ser versionadas. - - - - Uma entidade em estado persistente consiste de refer=C3=AA= ncias para outras entidades = - e inst=C3=A2ncias de tipos de valor.= Valores s=C3=A3o primitivos, = - cole=C3=A7=C3=B5es (n=C3=A3o o que tem dentro de uma cole= =C3=A7=C3=A3o), componentes e certos objetos = - imut=C3=A1veis. Entidades distintas, valores (em cole=C3= =A7=C3=B5es e componentes particulares) - s=C3=A3o persistidos e apagados por = acessibilidade. Visto que = - objetos value (e primitivos) s=C3=A3o persistidos e apagad= os junto com as entidades = - que os cont=C3=A9m e n=C3=A3o podem ser versionados indepe= ndentemente. Valores t=C3=AAm = - identidade n=C3=A3o independente, assim eles n=C3=A3o pode= m ser comuns para duas = - entidades ou cole=C3=A7=C3=B5es. - - - - - At=C3=A9 agora, n=C3=B3s estivemos usando o termo "classe = persistente" para referir = - a entidades. N=C3=B3s iremos continuar a fazer isto. Falan= do a rigor, por=C3=A9m, nem todas = - as classes definidas pelo usu=C3=A1rio com estados persist= entes s=C3=A3o entidades. Um = - componente =C3=A9 uma classe de usu= =C3=A1rio definida com valores = - sem=C3=A2nticos. Uma propriedade de Java de tipo = java.lang.String = - tamb=C3=A9m tem um valor sem=C3=AAntico. Dada esta defini= =C3=A7=C3=A3o, n=C3=B3s podemos dizer que = - todos os tipos (classes) fornecida pelo JDK tem tipo de va= lor sem=C3=A2ntico em Java, = - enquanto que tipos definidos pelo usu=C3=A1rio pode ser ma= peados com entidade ou valor = - de tipo sem=C3=A2ntico. Esta decis=C3=A3o pertence ao dese= nvolvedor da aplica=C3=A7=C3=A3o. Uma boa = - dica para uma classe entidade em um modelo de dom=C3=ADnio= s=C3=A3o refer=C3=AAncias comuns = - para uma inst=C3=A2ncia simples daquela classe, enquanto a= composi=C3=A7=C3=A3o ou agrega=C3=A7=C3=A3o = - geralmente se traduz para um valor de tipo. - - - - N=C3=B3s iremos rever ambos os conceitos durante toda a do= cumenta=C3=A7=C3=A3o. - - - - - O desafio pe mapear o sistema de tipo de Java (e a defini= =C3=A7=C3=A3o do desenvolvedor de = - entidades e tipos de valor) para o sistema de tipo SQL/ban= co de dados. A ponte entre ambos = - os sistemas =C3=A9 fornecido pelo Hibernate: para entidade= s que usam = - <class>, <subclass>= ; e assim por diante. = - Para tipos de valores n=C3=B3s usamos <propert= y>, = - <component>, etc, geralmente com = um atributo = - type. O valor deste atributo =C3=A9 o n= ome de um tipo de = - mapeamento do Hibernate. O Hibernate fornece mu= itos mapeamentos = - (para tipos de valores do JDK padr=C3=A3o) ut of the box. = Voc=C3=AA pode escrever os seus = - pr=C3=B3prios tipos de mapeamentos e implementar sua estra= t=C3=A9gia de convers=C3=A3o adaptada, = - como voc=C3=AA ver=C3=A1 adiante. - - - - Todos os tipos internos do hibernate exceto cole=C3=A7=C3= =B5es suportam sem=C3=A2nticas nulas. - - - - - - - Valores de tipos b=C3=A1sicos - - - O tipos internos de mapeamentos b=C3=A1sicos podem ser a g= rosso modo categorizado como: - - - integer, long, short, float, double= , character, byte, - boolean, yes_no, true_false - - - Tipos de mapeamentos de classes primitivas= ou wrapper Java especificos - (vendor-specific) para tipos de coluna SQL= . Boolean, = - boolean, yes_no s=C3=A3= o todas codifica=C3=A7=C3=B5es alternativas = - para um boolean ou java.lang.Boolean - do Java. - - - - - string - - - Um tipo de mapeamento de java.lan= g.String para - VARCHAR (ou VA= RCHAR2 no Oracle). - - - - - date, time, timestamp - - - Tipos de mapeamento de java.util.= Date e suas = - subclasses para os tipos SQL DATE= , - TIME e TIMESTA= MP = - (ou equivalente). - - - - - calendar, calendar_date - - - Tipo de mapeamento de java.util.C= alendar para = - os tipos SQL TIMESTAMP = e = - DATE (ou equivalente). - - - - - big_decimal, big_integer<= /term> - - - Tipo de mapeamento de java.math.B= igDecimal and - java.math.BigInteger pa= ra NUMERIC - (ou NUMBER no Oracle). - - - - - locale, timezone, currency - - - Tipos de mapeamentos de java.util= .Locale, - java.util.TimeZone e java.util.Currency - para VARCHAR (ou VARCHAR2 no Oracle). = - Inst=C3=A2ncias de f Locale e Currency = - s=C3=A3o mapeados para seus c=C3=B3digos I= SO. Inst=C3=A2ncias de TimeZone = - s=C3=A3o mapeados para seu ID. - - - - - class - - - um tipo de mapeamento de java.lan= g.Class para = - VARCHAR (ou V= ARCHAR2 no = - Oracle). Uma Class =C3= =A9 mapeada pelo = - seu nome qualificado (completo). - - - - - binary - - - Mapeia arrays de bytes para um tipo bin=C3= =A1rio de SQL apropriado. - - - - - text - - - Maps long Java strings to a SQL C= LOB or = - TEXT type. - Mapeia strings longas de Java para um tipo= SQL - CLOB ou TEXT. - - - - - serializable - - - Mapeia tipos Java serializ=C3=A1veis para = um tipo bin=C3=A1rio SQL apropriado. = - Voc=C3=AA pode tamb=C3=A9m indicar o tipo = serializable do = - Hibernate com o nome da classe ou interfac= e Java serializ=C3=A1vel que = - n=C3=A3o =C3=A9 padr=C3=A3o para um tipo b= =C3=A1sico. - - - - - clob, blob - - - Tipos de mapeamentos para as classes JDBC = java.sql.Clob and - java.sql.Blob. Estes ti= pos podem ser inconveniente para = - algumas aplica=C3=A7=C3=B5es, visto que o = objeto blob ou clob pode n=C3=A3o ser reusado = - fora de uma transa=C3=A7=C3=A3o. (Al=C3=A9= m disso, o suporte de driver =C3=A9 imcompleto e = - inconsistente.) - - - - - - imm_date, imm_time, imm_timestamp, im= m_calendar, imm_calendar_date, - imm_serializable, imm_binary - - - - Mapeando tipos para o que geralmente s=C3= =A3o consideradas tipos mut=C3=A1veis de = - Java, onde o Hibernate faz determinadas ot= imiza=C3=A7=C3=B5es apropriadas somente = - para tipos imut=C3=A1veis de Java, e a apl= ica=C3=A7=C3=A3o trata o objeto como imut=C3=A1vel. = - Por exemplo, voc=C3=AA n=C3=A3o deve chama= r Date.setTime() para = - uma inst=C3=A2ncia mapeada como = imm_timestamp. Para mudar = - o valor da propriedade, e ter a mudan=C3= =A7a feita persistente, a aplica=C3=A7=C3=A3o = - deve atribuir um novo objeto (nonidentical= ) =C3=A0 propriedade. = - - - - - = - - - - Identificadores =C3=BAnicos das entidades e cole=C3=A7=C3= =B5es podem ser de qualquer tipo = - b=C3=A1sico exceto binary, blo= b ou = - clob. (Identificadores compostos tamb= =C3=A9m s=C3=A3o permitidos, = - veja abaixo.) - - = - - Os tipos de valores b=C3=A1sicos t=C3=AAm suas constantes= Type = - correspondentes definidas em org.hibernate.Hibern= ate. Por exemplo, - Hibernate.STRING representa o tipo string. = - - - - - - Tipos de valores personalizados - - - =C3=89 relativamente f=C3=A1cil para desenvolvedores criar= seus pr=C3=B3prios tipos de valor. = - Por exemplo, voc=C3=AA pode querer persistir propriedades = do tipo = - java.lang.BigInteger para colunas VARCHAR. O = - Hibernate n=C3=A3o fornece um tipo correspondente para iss= o. Mas os tipos adaptados = - n=C3=A3o s=C3=A3o limitados a mapeamento de uma propriedad= e (ou elemento de cole=C3=A7=C3=A3o) a uma = - =C3=BAnica coluna da tabela. Assim, por exemplo, voc=C3=AA= p=C3=B4de ter uma propriedade Java = - getName()/setName() = do tipo = - java.lang.String que =C3=A9 persistido = para colunas = - FIRST_NAME, INITIAL,= SURNAME. = - - - = - - Para implementar um tipo personalizado, implemente org.hibernate.UserType - or org.hibernate.CompositeUserType e de= clare propriedades usando o nome = - qualificado da classe do tipo. Veja org.hibernate= .test.DoubleStringType = - para ver o tipo das coisas que s=C3=A3o poss=C3=ADveis. = - - - - - -]]> - - - Observe o uso da tag <column> par= a mapear uma propriedade = - para colunas m=C3=BAltiplas. = - - = - - As interfaces CompositeUserType, EnhancedUserType, - UserCollectionType, e UserVers= ionType = - fornecem suporte para usos mais especializados. - - = - - Voc=C3=AA pode mesmo fornecer par=C3=A2metros a um UserType no arquivo de mapeamento. = - Para isto, seu UserType deve implementa= r a interface = - org.hibernate.usertype.ParameterizedType. Para fornecer par=C3=A2metros a seu = - tipo personalizado, voc=C3=AA pode usar o elemento <type> em seus = - arquivos de mapeamento. = - - = - - - 0 - -]]> - - - O UserType pode agora recuperar o valor= para o par=C3=A2metro chamado = - default da Propriedade do passado a ele. = - - = - - Se voc=C3=AA usar freq=C3=BCentemente um determinado UserType, pode ser =C3=BAtil definir = - um nome mais curto para ele. Voc=C3=AA pode fazer isto usa= ndo o elemento = - <typedef>. Typedefs atribui um no= me a um tipo personalizado, e pode tamb=C3=A9m = - conter uma lista de valores default de par=C3=A2metro se o= tipo for parametrizado. - - = - - 0 -]]> - - ]]> - - - It is also possible to override the parameters supplied in= a typedef on a case-by-case basis - by using type parameters on the property mapping. - - = - - Even though Hibernate's rich range of built-in types and s= upport for components means you - will very rarely need to use a custom= type, it is nevertheless - considered good form to use custom types for (non-entity) = classes that occur frequently - in your application. For example, a MonetaryAmoun= t class is a good - candidate for a CompositeUserType, even= though it could easily be mapped = - as a component. One motivation for this is abstraction. Wi= th a custom type, your mapping = - documents would be future-proofed against possible changes= in your way of representing = - monetary values. - - - - = - - - - Mapping a class more than once - - It is possible to provide more than one mapping for a particul= ar persistent class. In this - case you must specify an entity name do d= isambiguate between instances - of the two mapped entities. (By default, the entity name is th= e same as the class name.) - Hibernate lets you specify the entity name when working with p= ersistent objects, when writing - queries, or when mapping associations to the named entity. - - = - - ... - - - - - - - - ... - -]]> - - - Notice how associations are now specified using entit= y-name instead of - class. - - - - - - SQL quoted identifiers - - You may force Hibernate to quote an identifier in the gene= rated SQL by enclosing the table or - column name in backticks in the mapping document. Hibernat= e will use the correct quotation - style for the SQL Dialect (usually doub= le quotes, but brackets for SQL - Server and backticks for MySQL). - - - - <= /id> - - ... -]]> - - - - = - - Metadata alternatives - = - - XML isn't for everyone, and so there are some alternative ways to = define O/R mapping metadata in Hibernate. - - - - Using XDoclet markup - - - Many Hibernate users prefer to embed mapping information direc= tly in sourcecode using - XDoclet @hibernate.tags. We will not cover = this approach in this - document, since strictly it is considered part of XDoclet. How= ever, we include the - following example of the Cat class with XDo= clet mappings. - - - - - - See the Hibernate web site for more examples of XDoclet and Hi= bernate. - - - - - - Using JDK 5.0 Annotations - - - JDK 5.0 introduced XDoclet-style annotations at the language l= evel, type-safe and - checked at compile time. This mechnism is more powerful than X= Doclet annotations and - better supported by tools and IDEs. IntelliJ IDEA, for example= , supports auto-completion - and syntax highlighting of JDK 5.0 annotations. The new revisi= on of the EJB specification - (JSR-220) uses JDK 5.0 annotations as the primary metadata mec= hanism for entity beans. - Hibernate3 implements the EntityManager of = JSR-220 (the persistence API), - support for mapping metadata is available via the Hi= bernate Annotations - package, as a separate download. Both EJB3 (JSR-220) and Hiber= nate3 metadata is supported. - - - - This is an example of a POJO class annotated as an EJB entity = bean: - - - orders; - - // Getter/setter and business methods -}]]> - - - Note that support for JDK 5.0 Annotations (and JSR-220) is sti= ll work in progress and - not completed. Please refer to the Hibernate Annotations modul= e for more details. - - = - - - - - Generated Properties - - Generated properties are properties which have their values ge= nerated by the - database. Typically, Hibernate applications needed to refresh - objects which contain any properties for which the database wa= s generating values. - Marking properties as generated, however, lets the application= delegate this - responsibility to Hibernate. Essentially, whenever Hibernate = issues an SQL INSERT - or UPDATE for an entity which has defined generated properties= , it immediately - issues a select afterwards to retrieve the generated values. - - - Properties marked as generated must additionally be non-insert= able and non-updateable. - Only versions, - timestamps, and - simple properti= es can be marked as - generated. - - - never (the default) - means that the given proper= ty value - is not generated within the database. - - - insert - states that the given property value is = generated on - insert, but is not regenerated on subsequent updates. Things like c= reated-date would - fall into this category. Note that even thought - version and - timestamp pro= perties can - be marked as generated, this option is not available there... - - - always - states that the property value is genera= ted both - on insert and on update. - - - - - Auxiliary Database Objects - - Allows CREATE and DROP of arbitrary database objects, in conju= nction with - Hibernate's schema evolution tools, to provide the ability to = fully define - a user schema within the Hibernate mapping files. Although de= signed specifically - for creating and dropping things like triggers or stored proce= dures, really any - SQL command that can be run via a java.sql.Statement.= execute() - method is valid here (ALTERs, INSERTS, etc). There are essent= ially two modes for - defining auxiliary database objects... - - - The first mode is to explicitly list the CREATE and DROP comma= nds out in the mapping - file: - - - ... - - CREATE TRIGGER my_trigger ... - DROP TRIGGER my_trigger - -]]> - - The second mode is to supply a custom class which knows how to= construct the - CREATE and DROP commands. This custom class must implement the - org.hibernate.mapping.AuxiliaryDatabaseObject interface. - - - ... - - - -]]> - - Additionally, these database objects can be optionally scoped = such that they only - apply when certain dialects are used. - - - ... - - - - - -]]> - - - + + Mapeamento O/R Bassico + + + Declara=C3=A7=C3=A3o de mapeamento + + + Object/relational mappings are usually defined in an XML docum= ent. The mapping + document is designed to be readable and hand-editable. The map= ping language is + Java-centric, meaning that mappings are constructed around per= sistent class + declarations, not table declarations. + + = + + Note that, even though many Hibernate users choose to write th= e XML by hand, + a number of tools exist to generate the mapping document, incl= uding XDoclet, + Middlegen and AndroMDA. + + + + Lets kick off with an example mapping: + + + + + + + + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + Discutir agora o conte=C3=BAdo deste documento de mapeamento.= Iremos apenas descrever = + os elementos do documento e atributos que s=C3=A3o utilizados= pelo Hibernate em tempo = + de execu=C3=A7=C3=A3o. O documento de mapeamento tamb=C3=A9m = cont=C3=A9m alguns atributos adicionais = + e opcionais al=C3=A9m de elementos que afetam os esquemas de = banco de dados exportados = + pela ferramenta de exporta=C3=A7=C3=A3o de esquemas. (Por exe= mplo, o atributo = + not-null). + + + + + + Doctype + + + Todos os mapeamentos de XML devem declarar o doctype exibi= do. O DTD atual pode = + ser encontrado na URL abaixo, no diret=C3=B3rio h= ibernate-x.x.x/src/org/ + hibernate ou no hibernate3.jar. O Hibernate sempre = + ir=C3=A1 procurar pelo DTD inicialmente no seu classpath. = Se voc=C3=AA tentar localizar + o DTD usando uma conex=C3=A3o de internet, compare a decla= ra=C3=A7=C3=A3o do seu DTD com o = + conte=C3=BAdo do seu classpath + + + + EntityResolver + + As mentioned previously, Hibernate will first attempt = to resolve DTDs in its classpath. The + manner in which it does this is by registering a custo= m org.xml.sax.EntityResolver + implementation with the SAXReader it uses to read in t= he xml files. This custom + EntityResolver recognizes two diffe= rent systemId namespaces. + + + + + a hibernate namespace is re= cognized whenever the + resolver encounteres a systemId starting with + http://hibernate.sourceforge.net/; the resolver + attempts to resolve these entities via the cla= sslaoder which loaded + the Hibernate classes. + + + + + a user namespace is recogni= zed whenever the + resolver encounteres a systemId using a classpath:// + URL protocol; the resolver will attempt to res= olve these entities + via (1) the current thread context classloader= and (2) the + classloader which loaded the Hibernate classes. + + + + + An example of utilizing user namespacing: + + + +]> + + + + + ... + + + &types; +]]> + + Where types.xml is a resource in th= e your.domain + package and contains a custom typedef. + + + + + + hibernate-mapping + + + Este elemento tem diversos atributos opcionais. Os atribut= os = + schema e catalog esp= ecificam que tabelas = + referenciadas neste mapeamento pertencem ao esquema e/ou a= o catalogo nomeado. = + Se especificados, os nomes das tabelas ir=C3=A3o ser quali= ficados no schema ou catalog dado. = + Se n=C3=A3o, os nomes das tabelas n=C3=A3o ser=C3=A3o qual= ificados. O atributo default-cascade + especifica qual estilo de cascata ser=C3=A1 ass= umido pelas propriedades e = + cole=C3=A7=C3=B5es que n=C3=A3o especificarm um atributo <= literal>cascade. O atributo = + auto-import nos deixa utilizar nomes de= classes n=C3=A3o qualificados = + na linguagem de consulta, por default. + + = + + + + + + + + + + + ]]> + + + + schema (opcional): O nome = do esquema do banco de dados. + + + + + catalog (opcional): O nom= e do cat=C3=A1logo do banco de dados. + + + + + default-cascade (opcional = =E2=80=93 default =C3=A9 nenhum + ): Um estilo cascata default. + + + + + default-access (opcional = =E2=80=93 default =C3=A9 property): = + A estrat=C3=A9gia que o Hibernate deve utiliz= ar para acessar todas as propridades. Pode = + ser uma implementa=C3=A7=C3=A3o pr=C3=B3pria = de PropertyAccessor. + + + + + default-lazy (opcional - d= efault =C3=A9 true): = + O valor default para atributos lazy<= /literal> da classe e dos = + mapeamentos de cole=C3=A7=C3=B5es. + + + + + auto-import ((opcional - d= efault =C3=A9 true): + Especifica se n=C3=B3s podemos usar nomes de = classess n=C3=A3o qualificados = + (das classes deste mapeamento) na linguagem d= e consulta. + + + + + package (opcional): Especi= fica um prefixo da package para = + assumir para nomes de classes n=C3=A3o qualif= icadas no documento de mapeamento. + + + + + = + + Se voce tem duas classes persistentes com o mesmo nome (n= =C3=A3o qualificadas), voc=C3=AA deve = + setar auto-import=3D"false". O Hiberna= te ir=C3=A1 gerar uma exce=C3=A7=C3=A3o se = + voc=C3=AA tentar setar duas classes para o mesmo nome "im= portado". + + + + Observe que o elemento hibernate-mapping permite a voc=C3=AA = + aninhar diversos mapeamentos de <class> persistentes, = + como mostrado abaixo. Entretanto, =C3=A9 uma boa pr=C3=A1= tica (e esperado por algumas = + ferramentas)o mapeamento de apenas uma classe persistente= simples (ou uma = + hierarquia de classes simples) em um arquivo de mapeament= o e nomea-la ap=C3=B3s = + a superclasse persistente, por exemplo: Cat.hbm.= xml, = + Dog.hbm.xml, ou se estiver usando her= an=C3=A7a, + Animal.hbm.xml. + + = + + + + class + + + Voc=C3=AA pode declarar uma classe persistente utilizando = o elemento + class: + + = + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + name (opcional): O nome da = classe Java inteiramente qualificado + da classe persistente (ou interface); Se o atr= ibuto =C3=A9 ausente, assume-se que o = + mapeamento =C3=A9 para intidades n=C3=A3o-POJO. + + + + + table (opcional =E2=80=93 d= efault para nomes de classes n=C3=A3o = + qualificadas) O nome da sua tabela do banco de= dados. + + + + + discriminator-value (opcion= al =E2=80=93 default para o nome da classe): = + Um valor que distingue subclasses individuais,= usadas para o comportamento polimorfico. = + Valores aceitos incluem null e not null + + + + + mutable (opcional - valor d= efault true): = + Especifica que instancias da classe s=C3=A3o (= ou n=C3=A3o) mut=C3=A1veis + + = + + + schema (opcional): Sobrep= =C3=B5e o nome do esquema especificado = + pelo elemento root <hibernate-mapp= ing>. + + = + + + catalog (opcional): Sobrep= =C3=B5e o nome do cat=C3=A1logo especificado = + pelo elemento root <hibernate-map= ping>. = + + = + + + proxy (opcional): Especific= a um interface para ser = + utilizada pelos proxies de inicializa=C3=A7=C3= =A3o tardia. Voc=C3=AA pode especificar o = + nome da pr=C3=B3pria classe. + + = + + + dynamic-update (opcional, v= alor default false): = + Especifica que o SQL de UPDATE deve ser gerado em tempo de = + execu=C3=A7=C3=A3o e conter apenas aquelas col= unas cujos valores foram alterados. + + = + + + dynamic-insert (opcional, v= alor default false): = + Especifica que o SQL de INSERT deve ser gerado em tempo de = + execu=C3=A7=C3=A3o e conter apenas aquelas col= unas cujos valores n=C3=A3o est=C3=A3o nulos. + + = + + + select-before-update (opci= onal, valor default false): = + Especifica que o Hibernate never deve executar um SQL de = + UPDATE a n=C3=A3o ser que c= om certeza um objeto est=C3=A1 atualmente modificado. = + Em certos casos (atualmente, apenas quando um = objeto transiente foi associado com uma nova + sess=C3=A3o utilizando update()), isto significa que o Hibernate ira executar = + uma instru=C3=A7=C3=A3o SQL de SELECT= adicional para determinar se um = + UPDATE =C3=A9 necess=C3=A1r= io nesse momento. + + = + + + polymorphism (opcional, def= ault para implicit): = + Determina se deve ser utilizado a query polimo= rfica implicita ou explicitamente. + + = + + + where (opicional) especific= a um comando SQL WHERE + arbitr=C3=A1rio para ser usado quando da recup= era=C3=A7=C3=A3o de objetos desta classe. + + = + + + persister (opcional): Espei= cifca uma ClassPersister = + customizada. + + = + + + batch-size (opcional, valor= default 1) especifica um = + "tamanho de lote" para a recupera=C3=A7=C3=A3o= de instancias desta classe pelo identificador. + + = + + + optimistic-lock (octional, = valor default version): = + Determina a estrat=C3=A9gia de bloqueio. + + = + + + lazy (opcional): A recupera= =C3=A7=C3=A3o tardia pode ser completamente = + desabilitada, setando lazy=3D"false"<= /literal>. + + = + + + entity-name (opcional, defa= ult para o nome da classe): O = + Hibernate3 permite uma classe ser mapeada mult= iplas vezes, (potencialmente,para = + diferentes tabelas), e permite mapeamentos de = entidades que s=C3=A3o representadas = + por Maps ou XML no n=C3=ADvel Java. Nestes cas= os, voc=C3=AA deve especificar um nome = + arbitr=C3=A1rio explicitamente para a entidade= . Veja = + e para maiores informa= =C3=A7=C3=B5es. + + + + + check (opcional): Uma expre= ss=C3=A3o SQL utilizada para gerar uma = + constraint de verifica=C3=A7=C3=A3o<= /emphasis> de m=C3=BAltiplas linhas para a gera=C3=A7=C3=A3o = + autom=C3=A1tica do esquema. + + + + + rowid (opcional): O Hiberna= te poder usar as assim chamadas = + ROWIDs em bancos de dados que a suportam. Por = exemplo, no Oracle, o Hibernate = + pode utilizar a coluna extra rowid para atuali= za=C3=A7=C3=B5es mais r=C3=A1pidas se voc=C3=AA = + configurar esta op=C3=A7=C3=A3o para = rowid. Um ROWID =C3=A9 uma implementa=C3=A7=C3=A3o = + que representa de maneira detalhada a localiza= =C3=A7=C3=A3o f=C3=ADsica de uma determinada = + tupla armazenado. + + + + + subselect (optional): Maps = an immutable and read-only entity + to a database subselect. Useful if you want to= have a view instead of a base table, + but don't. See below for more information. + subselect (opcional): Mapei= a uma entidade imutavel e somente + de leitura para um subconjunto do banco de da= dos. =C3=9Atil se voc=C3=AA quiser ter uma = + view em vez de uma tabela. Veja abaixo para ma= is informa=C3=A7=C3=B5es. + + + + + abstract (opcional): Utiliz= ada para marcar superclasses = + abstratas em hierarquias <union-su= bclass>. + + + + + = + + =C3=89 perfeitamente aceit=C3=A1vel para uma classe persit= ente nomeada ser uma interface. Voc=C3=AA dever=C3=A1 = + ent=C3=A3o declarar as classes implementadas desta interfa= ce utilizando o elemento = + <subclass>. Voc=C3=AA pode persis= tir qualquer classe de aninhada + estatica. Voc=C3=AA dever=C3=A1 espec= ificar o nome da classe usando a forma = + padr=C3=A3o, por exemplo: eg.Foo$Bar. + + + + Classes imut=C3=A1veis, mutable=3D"false", n=C3=A3o podem ser modificadas ou exclu=C3=ADdas = + pela aplica=C3=A7=C3=A3o. Isso permite ao Hibernate fazer = alguns aperfei=C3=A7oamentos de performance. + + = + + O atributo opcional proxy habilita a in= icializa=C3=A7=C3=A3o tardia das = + inst=C3=A2ncias persistentes da classe. O Hibernate ir=C3= =A1 retornar CGLIB proxies como implementado = + na interface nomeada. O objeto persistente atual ser=C3= =A1 carregado quando um m=C3=A9todo do proxy = + for invocado. Veja "Inicializando cole=C3=A7=C3=B5es e pro= xies" abaixo. + + = + Polimorfismo impl=C3=ADcito signifi= ca que inst=C3=A2ncias de uma classe = + ser=C3=A3o retornada por uma query que d=C3=A1 nome a qual= quer superclasse ou interface implementada, = + ou a classe e as instancias de qualquer subclasse da class= e ser=C3=A1 retornada por umq query = + que nomeia a classe por si. Polimorfismo expl=C3= =ADcito significa que = + instancias da classe ser=C3=A3o retornadas apenas por quer= ies que explicitamente nomeiam a = + classe e que queries que nomeiam as classes ir=C3=A3o reto= rnar apenas instancias de subclasses = + mapeadas dentro da declara=C3=A7=C3=A3o <class= > como uma = + <subclass> ou <joined= -subclass>. + Para a maioria dos casos, o valor default polymor= phism=3D"implicit", = + =C3=A9 apropriado. Polimorfismo explicito =C3=A9 =C3=BAtil= quando duas classes distintas est=C3=A3o mapeadas = + para a mesma tabela (isso permite um classe "peso leve" qu= e contem um subconjunto = + de colunas da tabela). + + = + + O atributo persister deixa voc=C3=AA cu= stomizar a estrat=C3=A9gia de persist=C3=AAncia = + utilizada para a classe. Voc=C3=AA pode, por exemplo, espe= cificar sua pr=C3=B3rpia subclasse do = + org.hibernate.persister.EntityPersister= ou voc=C3=AA pode criar = + uma implementa=C3=A7=C3=A3o completamente nova da interfa= ce = + org.hibernate.persister.ClassPersister = que implementa a persist=C3=AAncia = + atrav=C3=A9s de, por exemplo, chamadas a stored procedeure= s, serializa=C3=A7=C3=A3o de arquivos flat ou = + LDAP. Veja org.hibernate.test.CustomPersister para um exemplo = + simples (de "persistencia" para uma Hashtable). + + = + + Observe que as configura=C3=A7=C3=B5es dynamic-up= date e = + dynamic-insert n=C3=A3o sao herdadas pe= las subclasses e assim podem tambem = + ser especificadas em elementos <subclass> or = + <joined-subclass>. Estas configur= a=C3=A7=C3=B5es podem incrementar a = + performance em alguns casos, mas pode realmente diminuir a= performance em outras. = + Use-as de forma bastante criteriosa. + + = + + O uso de select-before-update geralment= e ir=C3=A1 diminuir a performance. Ela =C3=A9 = + muito =C3=BAtil para prevenir que uma trigger de atualiza= =C3=A7=C3=A3o no banco de dados seja ativada = + desnecessariamente, se voc=C3=AA reconectar um n=C3=B3 de = uma instancia desconectada em uma = + Session. + + = + + Se voc=C3=AA ativar dynamic-update, vo= c=C3=AA ter=C3=A1 de escolher = + a estrat=C3=A9gia de bloqueio otimista: + + + + + version verifica a vers=C3=A3o = e a hora das colunas + + + + + all cverifica todas as colunas + + + + + dirty verifica as colunas modif= icadas, permitindo = + alguns updates concorrentes + + + + + none n=C3=A3o utiliza o bloquei= o otimista + + + + + N=C3=B3s recomendamos com muita enfas= e que voc=C3=AA utilize a = + vers=C3=A3o e a hora das colunas para o bloqueio otimista = com o Hibernate. = + Esta =C3=A9 a melhor estrat=C3=A9gia com respeito a perfor= mance e =C3=A9 a =C3=BAnica estrat=C3=A9gia = + que trata corretamente as modifica=C3=A7=C3=B5es efetuadas= em instancias desconectadas = + (por exemplo, quando Session.merge() = =C3=A9 utilizado). + + + + + N=C3=A3o ha diferen=C3=A7a entre uma view e uma tabela par= a o mapeamento do Hibernate, e como = + esperado isto =C3=A9 transparente no n=C3=ADvel do banco d= e dados (observe que alguns bancos de = + dados n=C3=A3o suportam views apropriadamente, especialmen= te com updates). Algumas vezes, = + voc=C3=AA quer utilizar uma view, ma sn=C3=A3o pode cria-l= a no banco de dados (por exemplo, = + com um esquema legado). Neste caso, voc=C3=AA pode mapear = uma entidade imut=C3=A1vel e de = + somente leitura, para uma dada express=C3=A3o SQL, que rep= resenta um subselect: + + + + + select item.name, max(bid.amount), count(*) + from item + join bid on bid.item_id =3D item.id + group by item.name + + + + + ... +]]> + + + Declare as tabelas para sincronizar com esta entidade, gar= antindo que o auto-flush = + ocorra corretamente, e que as queries para esta entidade d= erivada n=C3=A3o retornem dados = + desatualizados. O <subselect> est= =C3=A1 dispon=C3=ADvel tanto como um = + atributo como um elemento mapeado nested. + + + + + + id + + + Classes mapeadas precisam declarar a = coluna de chave primaria da = + tabela do banco de dados. Muitas classes ir=C3=A3o tambem = ter uma propriedade ao estilo = + Java-Beans declarando o identificador unico de uma instanc= ia. O elemento = + <id> define o mapeamento desta pr= opriedade para a chave prim=C3=A1ria. + + = + + + + + + + + + + node=3D"element-name|@attribute-name|element/@attribute|." + + +]]> + + + + name (opcional): O nome do = identificador. + + + + + type (opcional): Um nome qu= e indica o tipo no Hibernate. + + + + + column (opcional =E2=80=93 = default para o a propridade name): O = + nome coluna chave primaria. + + + + + unsaved-value (opcional - d= efault para um valor "sens=C3=ADvel"): = + Uma propriedade de identifica=C3=A7=C3=A3o que= indica que a instancia foi novamente = + instanciada (unsaved), diferenciando de instan= cias desconectadas que foram = + salvas ou carregadas em uma sess=C3=A3o anteri= or. + + = + + + access (opcional - valor de= fault property): A = + estrat=C3=A9gia que o Hiberante deve utilizar = para acessar o valor da propriedade + + + + + = + + Se o atributo name n=C3=A3o for declara= do, assume-se que a classe n=C3=A3o tem = + a propriedade de identifica=C3=A7=C3=A3o. + + = + + O atributo unsaved-value n=C3=A3o =C3= =A9 mais necess=C3=A1rio no Hibernate 3. + + + + H=C3=A1 declara=C3=A7=C3=A3o alternativa <com= posite-id> permite o acesso a = + dados legados com chaves compostas. N=C3=B3s desencorajamo= s fortemente o seu uso por = + qualquer pessoa. + + = + + Generator + + + O elemento filho opcional <generator> nomeia uma classe Java = + usada para gerar identificadores unicos para instancia= s de uma classe persistente. = + Se algum par=C3=A2metro =C3=A9 requerido para configur= ar ou inicializar a instancia geradora, = + eles s=C3=A3o passados utilizando o elemento = <param>. + + + + + uid_table + next_hi_value_column + +]]> + + + Todos os generators implementam a interface = org.hibernate.id.IdentifierGenerator. = + Esta =C3=A9 uma interface bem simples; algumas aplica= =C3=A7=C3=B5es podem prover sua pr=C3=B3pria implementa=C3=A7=C3=A3o = + esepecializada. Entretanto, o Hibernate disponibiliza = um conjunto de implementa=C3=A7=C3=B5es internamente. = + H=C3=A1 nomes de atalhos para estes generators pr=C3= =B3prios: + + + increment + + + gera identificadores dos tipos lo= ng, short ou + int que s=C3=A3o unicos= apenas quando nenhum outro processo est=C3=A1 = + inserindo dados na mesma tabela. N=C3=A3o utilize em ambientes = + de cluster. + + + + + identity + + + suporta colunas de identidade em DB2, MyS= QL, MS SQL Server, Sybase e = + HypersonicSQL. O identificador retornado = =C3=A9 do tipo long, = + short ou int. + + + + + sequence + + + utiliza uma sequence em DB2, PostgreSQL, O= racle, SAP DB, McKoi ou um = + generator no Interbase. O identificador de= retorno =C3=A9 do tipo + long, short o= u int. + + + + + hilo + + + utiliza um algoritmo hi/lo para gerar de f= orma eficiente identificadores do tipo = + long, short ou int, + a partir de uma tabela e coluna fornecida = (por default = + hibernate_unique_key e = next_hi) = + como fonte para os valores hi. O algoritmo= hi/lo gera identificadores que s=C3=A3o = + =C3=BAnicos apenas para um banco de dados = particular. = + + + + + seqhilo + + + utiliza um algoritmo hi/lo para gerar de f= orma eficinete identificadores do tipo = + long, short ou int, + a partir de uma sequence de banco de dados= fornecida. + + + + + uuid + + + utiliza um algortimo UUID de 128-bits para= gerar identificadores do = + tipo string, unicos em uma rede(o endere= =C3=A7o IP =C3=A9 utilizado). O UUID =C3=A9 = + codificado como um string de digitos hexad= ecimais de tamanho 32. + + + + + guid + + + utiliza um string GUID gerado pelo banco d= e dados no MS SQL Server = + e MySQL. + + + + + native + + + seleciona entre identity, sequence = + ou hilo dependendo das = capacidades do banco de dados = + utilizado. + + + + + assigned + + + deixa a aplica=C3=A7=C3=A3o definir um ide= ntificador para o objeto antes que o = + save() seja chamado. Es= ta =C3=A9 a estrat=C3=A9gia default = + se nenhum elemento <generator&= gt; =C3=A9 especificado. + + + + + select + + + retorna a chave primaria recuperada por um= a trigger do banco de = + dados, selecionado uma linha pela chave = =C3=BAnica e recuperando o valor = + da chave prim=C3=A1ria. + + + + + foreign + + + utiliza o identificador de um outro objeto= associado. Normalmente utilizado = + em conjunto com uma associa=C3=A7=C3=B5a d= e chave prim=C3=A1ria do tipo + <one-to-one>. + + + + + sequence-identity + + + a specialized sequence generation strategy= which utilizes a + database sequence for the actual value gen= eration, but combines + this with JDBC3 getGeneratedKeys to actual= ly return the generated + identifier value as part of the insert sta= tement execution. This + strategy is only known to be supported on = Oracle 10g drivers + targetted for JDK 1.4. Note comments on t= hese insert statements + are disabled due to a bug in the Oracle dr= ivers. + + + + + + + + = + + Algoritmo Hi/lo + + Os geradores hilo e seqhil= o fornecem duas = + implementa=C3=A7=C3=B5es alternativas do algoritmo hi/= lo, uma solu=C3=A7=C3=A3o preferencial para a gera=C3=A7=C3=A3o = + de identificadores. A primeira implementa=C3=A7=C3=A3o= requer uma tabela especial do banco de = + dados para manter o proximo valor "hi" dispon=C3=ADvel= . A segunda utiliza uma seq=C3=BC=C3=AAncia = + do estilo Oracle (quando suportado). = + + + + + hi_value + next_value + 100 + +]]> + + + + hi_value + 100 + +]]> + + + Infelizemente, voce n=C3=A3o pode utilizar hi= lo quando estiver = + fornecendo sia propria Connection = para o Hibernate. Quando o = + Hibernate est=C3=A1 usando um datasource do servidor d= e aplica=C3=A7=C3=B5es para obter conex=C3=B5es = + suportadas com JTA, voc=C3=AA precisa configurar adequ= adamente o = + hibernate.transaction.manager_lookup_class. + + + = + + UUID algorithm + + O UUID contem: o endere=C3=A7o IP, hora de inicio da J= VM (com precis=C3=A3o de um quarto = + de segundo), a hora do sistema e um valor contador (un= ico dentro da JVM). = + N=C3=A3o =C3=A9 possivel obter o endere=C3=A7o MAC ou = um endere=C3=A7o de mem=C3=B3ria do c=C3=B3digo Java, = + assim este =C3=A9 o melhor que pode ser feito sem util= izar JNI. + + + + + Colunas de identidade e sequencias + + Para bancos de dados que suportam colunas de identidad= e (DB2, MySQL, Sybase, = + MS SQL), voc=C3=AA pode utilizar uma gera=C3=A7=C3=A3o= de chave identity. = + Para bancos de dados que suportam sequencias (DB2, Ora= cle, PostgreSQL, Interbase, = + McKoi, SAP DB) voce pode utilizar a gera=C3=A7=C3=A3o = de chaves no estilo = + sequence. As duas estrat=C3=A9gias = requerem duas consultas SQL = + para inserir um novo objeto. = + + + + + person_id_sequence + +]]> + + + +]]> + = + + Para desenvolvimento multi-plataforma, a estrat=C3=A9g= ia native = + ir=C3=A1 escolher entre as estrat=C3=A9gias i identity, = + sequence e hilo,= dependendo das = + capacidades do banco de dados utilizado. + + + = + + Identificadores especificados + + Se voc=C3=AA quer que a aplica=C3=A7=C3=A3o especifiqu= e os identificadores = + (em vez do Hibernate ger=C3=A1-los) voc=C3=AA deve uti= lizar o gerador = + assigned. Este gerador especial ir= =C3=A1 utilizar o valor = + do identificador especificado para a propriedade de id= entifica=C3=A7=C3=A3o do objeto. = + Este gerador =C3=A9 usado quando a chave primaria =C3= =A9 a chave natural em vez de uma = + surrogate key. Este =C3=A9 o comportamento padr=C3=A3o= se voc=C3=AA n=C3=A3o especificar = + um elemento <generator>. = + + = + + Escolher o gerador assigned faz com= que o Hibernate = + utilize unsaved-value=3D"undefined"= , for=C3=A7ando o Hibernate = + ir at=C3=A9 o banco de dados para determinar se uma in= st=C3=A2ncia est=C3=A1 transiente ou = + desasociada, a menos que haja uma vers=C3=A3o ou uma p= ropriedade timestamp, = + ou voc=C3=AA pode definir Interceptor.isUnsav= ed(). + + + + + Chaves prim=C3=A1rias geradas por triggers + + Apenas para sistemas legados (o Hibernate nao gera DDL= com triggers). + + + + + socialSecurityNumber + +]]> + + + No exemplo acima, h=C3=A1 uma =C3=BAnica propriedade c= om valor nomeada = + socialSecurityNumber definida pela= classe, = + uma chave natural, e uma surrogate key nomeada = + person_id cujo valor =C3=A9 gerado = pro uma trigger. + + = + + + + + Enhanced identifier generators + = + + Starting with release 3.2.3, there are 2 new generators which represent= a re-thinking of 2 different + aspects of identifier generation. The first aspect is database portabi= lity; the second is optimization + (not having to query the database for every request for a new identifie= r value). These two new + generators are intended to take the place of some of the named generato= rs described above (starting + in 3.3.x); however, they are included in the current releases and can b= e referenced by FQN. + + = + + The first of these new generators is org.hibernate.id.enhanced= .SequenceStyleGenerator + which is intended firstly as a replacement for the sequence generator and secondly as + a better portability generator than native (because = native + (generally) chooses between identity and se= quence which have + largely different semantics which can cause subtle isssues in applicati= ons eyeing portability). + org.hibernate.id.enhanced.SequenceStyleGenerator how= ever achieves portability in + a different manner. It chooses between using a table or a sequence in = the database to store its + incrementing values depending on the capabilities of the dialect being = used. The difference between this + and native is that table-based and sequence-based st= orage have the same exact + semantic (in fact sequences are exactly what Hibernate tries to emmulat= e with its table-based + generators). This generator has a number of configuration parameters: + + + + sequence_name (optional, defaults to hib= ernate_sequence): + The name of the sequence (or table) to be used. + + + + + initial_value (optional, defaults to 1): The initial + value to be retrieved from the sequence/table. In sequence creation= terms, this is analogous + to the clause typical named "STARTS WITH". + + + + + increment_size (optional, defaults to 1<= /literal>): The value by + which subsequent calls to the sequence/table should differ. In sequ= ence creation terms, this + is analogous to the clause typical named "INCREMENT BY". + + + + + force_table_use (optional, defaults to f= alse): Should + we force the use of a table as the backing structure even though the= dialect might support + sequence? + + + + + value_column (optional, defaults to next= _val): Only + relevant for table structures! The name of the column on the table = which is used to + hold the value. + + + + + optimizer (optional, defaults to none): + See + + + + + + The second of these new generators is org.hibernate.id.enhance= d.TableGenerator which + is intended firstly as a replacement for the table g= enerator (although it actually + functions much more like org.hibernate.id.MultipleHiLoPerTable= Generator) and secondly + as a re-implementation of org.hibernate.id.MultipleHiLoPerTabl= eGenerator utilizing the + notion of pluggable optimiziers. Essentially this generator defines a = table capable of holding + a number of different increment values simultaneously by using multiple= distinctly keyed rows. This + generator has a number of configuration parameters: + + + + table_name (optional, defaults to hibern= ate_sequences): + The name of the table to be used. + + + + + value_column_name (optional, defaults to next_val): + The name of the column on the table which is used to hold the value. + + + + + segment_column_name (optional, defaults to sequence_name): + The name of the column on the table which is used to hold the "segem= ent key". This is the + value which distinctly identifies which increment value to use. + + + + + segment_value (optional, defaults to def= ault): + The "segment key" value for the segment from which we want to pull i= ncrement values for + this generator. + + + + + segment_value_length (optional, defaults to 255): + Used for schema generation; the column size to create this segment k= ey column. + + + + + initial_value (optional, defaults to 1): + The initial value to be retrieved from the table. + + + + + increment_size (optional, defaults to 1<= /literal>): + The value by which subsequent calls to the table should differ. + + + + + optimizer (optional, defaults to ): + See + + + + + + = + + Identifier generator optimization + + For identifier generators which store values in the database, it is ine= fficient for them to hit the + database on each and every call to generate a new identifier value. In= stead, you'd ideally want to + group a bunch of them in memory and only hit the database when you have= exhausted your in-memory + value group. This is the role of the pluggable optimizers. Currently = only the two enhanced generators + ( support this notio= n. + + + + none (generally this is the default if no optimiz= er was specified): This + says to not perform any optimizations, and hit the database each and= every request. + + + + + hilo: applies a hi/lo algorithm around the databa= se retrieved values. The + values from the database for this optimizer are expected to be seque= ntial. The values + retrieved from the database structure for this optimizer indicates t= he "group number"; the + increment_size is multiplied by that value in mem= ory to define a group + "hi value". + + + + + pooled: like was discussed for hilo, this optimizers + attempts to minimize the number of hits to the database. Here, howe= ver, we simply store + the starting value for the "next group" into the database structure = rather than a sequential + value in combination with an in-memory grouping algorithm. increment_size + here refers to the values coming from the database. + + + + + + = + + + composite-id + + + node=3D"element-name|." + + + + ...... +]]> + + + Para tabelas com uma chave composta, voc=C3=AA pode mapear= m=C3=BAltiplas propriedades = + da classe como propriedades de identifica=C3=A7=C3=A3o. O = elemento = + <composite-id> aceita o mapeament= o da propriedade = + <key-property> e mapeamentos = + <key-many-to-one>como elements fi= lhos. + + = + + + +]]> + + + Sua classe persistente precisa sobre = escrever = + equals() e hashCode() para implementar = + identificadores compostos igualmente. E precisa tamb=C3=A9= m implementar = + Serializable. + + + + Infelizmente, esta solu=C3=A7=C3=A3o para um identificador= composto significa que um objeto = + persistente =C3=A9 seu pr=C3=B3prio identificador. N=C3=A3= o h=C3=A1 outro "handle" que o pr=C3=B3prio objeto. = + Voc=C3=AA mesmo precisa instanciar uma inst=C3=A2ncia de o= utra classe persistente e preencher = + suas propriedades de identifica=C3=A7=C3=A3o antes que voc= =C3=AA possa dar um load() + para o estado persistente associado com uma chave composta= . Nos chamamos esta = + solu=C3=A7=C3=A3o de identificador composto embe= dded e n=C3=A3o aconselhamos = + para aplica=C3=A7=C3=B5es s=C3=A9rias. = + + = + + Uma segunda solu=C3=A7=C3=A3o =C3=A9 o que podemos chamar = de identificador composto = + mapped quando a propriedades de ident= ifica=C3=A7=C3=A3o nomeadas dentro do = + elemento <composite-id> est=C3=A3= o duplicadas tando na classe = + persistente como em uma classe de identifica=C3=A7=C3=A3o = separada. = + + = + + + +]]> + + + No exemplo, ambas as classes de identifica=C3=A7=C3=A3o co= mpostas, MedicareId, = + e a pr=C3=B3pria classe entidade tem propriedades nomeadas= medicareNumber = + e dependent. A classe identificadora pr= ecisa sobrepor = + equals() e hashCode() e implementar = + Serializable. A desvantagem desta solu= =C3=A7=C3=A3o =C3=A9 obvia =E2=80=93 = + duplica=C3=A7=C3=A3o de c=C3=B3digo. + + = + + Os seguintes atributos =C3=A3o utilizados para especificar= o mapeamento de = + um identificador composto: + + + + + + mapped mapped (opcional, valor = default false + ): indica que um identificar composto ma= peado =C3=A9 usado, e que as = + propriedades de mapeamento contidas refere-se tant= o a classe entidade e = + a classe de identifica=C3=A7=C3=A3o composta. + + + + + class (opcional, mas requerida = para um identificar composto = + mapeado): A classe usada como um identificador com= posto. = + + + + + + N=C3=B3s iremos descrever uma terceira e as vezes mais con= veniente solu=C3=A7=C3=A3o, onde o = + identificador composto =C3=A9 implementado como uma classe= componente na = + . Os atributos d= escritos abaixo aplicam-se = + apenas para esta solu=C3=A7=C3=A3o: + + + + + + name (opcional, requerida para = esta solu=C3=A7=C3=A3o): Uma = + propriedade do tipo componente que armazena o iden= tificador composto = + (veja cap=C3=ADtulo 9) = + + + + + access (opcional - valor defaul= t property): = + A estart=C3=A9gia Hibernate que deve ser utilizada= para acessar o valor da propriedade. + + + + + class (opcional - valor default= para o tipo de propriedade = + determiando por reflex=C3=A3o) : A classe componen= te utilizada como um identificador = + composto (veja a pr=C3=B3xima sess=C3=A3o). + + + + = + + Esta terceira solu=C3=A7=C3=A3o, um componente d= e identifica=C3=A7=C3=A3o, =C3=A9 o que n=C3=B3s = + recomendamos para a maioria das aplica=C3=A7=C3=B5es. + + = + + = + + discriminator + + + O elemento <discriminator> =C3= =A9 necess=C3=A1rio para persist=C3=AAncia = + polim=C3=B3rfica utilizando a estrat=C3=A9gia de mapeament= o table-per-class-hierarchy e declara = + uma coluna discriminadora da tabela. A coluna discriminado= ra contem valores de marca=C3=A7=C3=A3o = + que dizem a camada de persist=C3=AAncia qual subclasse ins= tanciar para uma linha particular. = + Um restrito conjunto de tipos que podem ser utilizados: string, = + character, integer, = byte, = + short, boolean, = + yes_no, true_false. + + = + + + + + + + + + ]]> + + + + column (opcional - valor de= fault class) = + o nome da coluna discriminadora + + + + + type (opcional - valor defa= ult string) = + o nome que indica o tipo Hibernate + + = + + + force (opcional - valor def= ault false) = + "for=C3=A7a" o Hibernate a especificar valores= discriminadores permitidos mesmo = + quando recuperando todas as instancias da clas= se root. + + = + + + insert (opcional - valor de= fault para true) = + sete isto para false se sua= coluna discriminadora =C3=A9 tamb=C3=A9m = + parte do identificador composto mapeado. (Diz = ao Hibernate para n=C3=A3o incluir a = + coluna em comandos SQL INSERTs). = + + + + + formula (opcional) uma expr= ess=C3=A3o SQL arbitraria que =C3=A9 e + xecutada quando um tipo tem que ser avaliado. = Permite discrimina=C3=A7=C3=A3o baseada = + em conte=C3=BAdo. + + + + + + + Valores atuais de uma coluna discriminada s=C3=A3o especif= icados pelo atributo = + discriminator-value da <cla= ss> = + e elementos da <subclass>. + + = + + O atributo force =C3=A9 util (apenas) = em tabelas contendo linhas com = + valores discriminadores "extras" que n=C3=A3o est=C3=A3o m= apeados para uma classe persistente. = + Este n=C3=A3o =C3=A9 geralmente o caso. + + + + Usando o atributo formula voce pode dec= larar uma express=C3=A3o SQL = + arbitr=C3=A1ria que sera utilizada para avaliar o tipo de = uma linha : + + + ]]> + + + + + version (optional) + = + + O elemento <version> =C3=A9 opcio= nal e indica que a tabela = + possui dados versionados. Isto =C3=A9 particularmente =C3= =BAtil se voc=C3=AA planeja utilizar = + transa=C3=A7=C3=B5es longas (veja aba= ixo): + + = + + + + + + + + + + + ]]> + + + + column (opcional - default = a a propriedade name): O nome da = + coluna mantendo o numero da vers=C3=A3o = + + = + + + name: O nome da propriedade= da classe persistente. + + + + + type (opcional - valor defa= ult para integer): = + O tipo do numero da vers=C3=A3o + + = + + + access (opcional - valor de= fault property): = + A estrat=C3=A9gia Hibernate que deve ser usada= para acessar o valor da propriedade. + + + + + unsaved-value (opcional = =E2=80=93 valor default para undefined + ): Um valor para a propriedade vers= =C3=A3o que indica que uma instancia =C3=A9 = + uma nova instanciada (unsaved), distinguindo d= e instancias desconectadas que foram = + salvas ou carregadas em sess=C3=B5es anteriore= s. ((undefined especifica = + que o valor da propriedade de identifica=C3=A7= =C3=A3o deve ser utilizado). + + + + + generated (optional - defau= lts to never): + Specifies that this version property value is = actually generated by the database. + See the discussion of generated properties. + generated (opcional - valor= default never): = + Especifica que valor para a propriedade vers= =C3=A3o =C3=A9 na verdade gerado pelo banco de = + dados. Veja a discuss=C3=A3o da Se=C3=A7=C3=A3= o = + generated = properties. = + + + + + insert (opcional - valor de= fault para true): = + Especifica se a coluna de vers=C3=A3o deve ser= inclu=C3=ADda no comando SQL de insert. = + Pode ser configurado como false se a coluna do banco de dados = + est=C3=A1 definida com um valor default de 0. + + + + + = + + N=C3=BAmeros de vers=C3=A3o podem ser dos tipos Hibernate = long, = + integer, short, timestamp ou + calendar. + + = + + A vers=C3=A3o de uma propriedade timestamp nunca deve ser = nula para uma instancia = + desconectada, assim o Hibernate ir=C3=A1 identificar qualq= uer inst=C3=A2ncia com uma vers=C3=A3o = + nula ou timestamp como transiente, n=C3=A3o importando qua= l estrat=C3=A9gia para foi = + especificada para unsaved-value. Declarando uma vers=C3=A3o = + nula ou a propriedade timestamp =C3=A9 um caminho f=C3=A1c= il para tratar problemas com = + reconex=C3=B5es transitivas no Hibernate, especialmente = =C3=BAteis para pessoas utilizando = + identificadores assinaldados ou chaves compostas! + + + = + + timestamp (optional) + + + O elemento opcional <timestamp> i= ndica que uma tabela cont=C3=A9m = + dados timestamped. Isso tem por objetivo dar uma alternati= va para versionamento. Timestamps = + s=C3=A3o por natureza uma implementa=C3=A7=C3=A3o menos se= gura do locking otimista. Entretanto, algumas = + vezes a aplica=C3=A7=C3=A3o pode usar timestamps em outros= caminhos. + + = + + + + + + + + + = + ]]> + + + + column (opcional - valor de= fault para a propriedade name): = + O nome da coluna que mantem o timestamp. + + = + + + name: O nome da propriedade= no estilo JavaBeans do = + tipo Date ou Times= tamp da classe = + persistente Java. + + + + + access (opcional - valor de= fault para property): = + A estretagia Hibernate que deve ser utilizada = para acessar o valor da propriedade. + + + + + unsaved-value (opcional - v= alor default null): = + Uma propriedade para a vers=C3=A3o de que indi= ca que uma inst=C3=A2ncia =C3=A9 uma nova instanciada = + (unsaved), distinguindo-a de instancias descon= ectadas que foram salvas ou carregadas = + em sess=C3=B5es previas. (undefined especifica que um valor de = + propriedade de identifica=C3=A7=C3=A3o deve se= r utilizado) + + + + + source (opcional - valor d= efault para vm): = + De onde o Hibernate deve recuperar o valor tim= estamp? Do banco de dados ou da JVM = + corrente? Timestamps baseados em banco de dado= s levam a um overhead porque o = + Hibernate precisa acessar o banco de dados par= a determinar o "pr=C3=B3ximo valor", mas =C3=A9 = + mais seguro para uso em ambientes de "cluster"= . Observe tamb=C3=A9m, que nem todos = + Dialects suportam a recuper= a=C3=A7=C3=A3o do timestamp corrente do banco = + de dados, enquando outros podem n=C3=A3o ser s= eguros para utiliza=C3=A7=C3=A3o em bloqueios = + pela falta de precis=C3=A3o (Oracle 8 por exem= plo) + + + + + generated (opcional - valor= default never): = + Especifica que o valor da propriedade timestam= p =C3=A9 gerado pelo banco de dados. = + Veja a discuss=C3=A3o generated properties. = + + + + + = + + Observe que <timestamp> =C3=A9 eq= uivalente a = + <version type=3D"timestamp">. E = + <timestamp source=3D"db"> =C3=A9 = equivalente a = + <version type=3D"dbtimestamp">. + + + + + + property + + + O elemento <property> declara uma= propriedade = + persistente de uma classe, no estilo JavaBean. = + + = + + + + + + + + + + + + + + + + + = + ]]> + + + + name: o nome da propriedade= , iniciando com letra min=C3=BAscula. + + = + + + column (opcional - default = para a propriedade name): o nome = + da coluna mapeada do banco de dados, Isto pode= tamb=C3=A9m ser especificado pelo(s) = + elemento(s) <column> = aninhados. + + + + + + type (opcional): um nome qu= e indica o tipo Hibernate. + + + + + update, insert (opcional - = valor default true): + especifica que as colunas mapeadas devem ser i= ncluidas nas instru=C3=A7=C3=B5es SQL de = + UPDATE e/ou INSERT= . Setar ambas para to = + false permite uma propridad= e "derivada" pura cujo valor =C3=A9 = + inicializado de outra propriedade que mapeie a= mesma coluna(s) ou por uma trigger = + ou outra aplica=C3=A7=C3=A3o. + + + + + formula (opcional): uma ex= press=C3=A3o SQL que definie o valor para = + uma propriedade calculada= . Propriedades calculadas nao tem = + uma coluna de mapeamento para elas. + + + + + access (opcional =E2=80=93 = valor default property): = + A estrat=C3=A9gia que o Hibernate deve utiliza= r para acessar o valor da propriedade + + + + + lazy (opcional - valor defa= ult para false): = + Especifica que esta propriedade deve ser trazi= da de forma "lazy" quando a = + instancia da vari=C3=A1vel =C3=A9 acessada pel= a primeira vez (requer instrumenta=C3=A7=C3=A3o = + bytecode em tempo de cria=C3=A7=C3=A3o). + + + + + unique (opcional): Habilita= a gera=C3=A7=C3=A3o de DDL de uma = + unica constraint para as colunas. Assim, permi= te que isto seja o = + alvo de uma property-ref. + + + + + not-null (opcional): Habili= ta a gera=C3=A7=C3=A3o de DDL de uma = + constraint de nulidade para as colunas. + + + + + optimistic-lock (opcional -= valor default true): + Especifica se mudan=C3=A7as para esta propried= ade requerem ou n=C3=A3o bloqueio otimista. = + Em outras palavras, determina se um incremento= de vers=C3=A3o deve ocorrer quando = + esta propriedade est=C3=A1 suja. + + + + + generated (opcional - valor= default never): = + Especifica que o valor da propriedade =C3=A9 n= a verdade gerado pelo banco de dados. + Veja a discuss=C3=A3o da se=C3=A7=C3=A3o = + generated = properties. + + + + + + + typename pode ser: + + + + + + The name of a Hibernate basic type (eg. i= nteger, string, character, + date, timestamp, float, binary, serializable, obje= ct, blob). + O nome do tipo basico do Hibernate (ex., = integer, string, character, + date, timestamp, float, binary, serializable, obje= ct, blob). + + + + + O nome da classe Java com um tipo b=C3=A1sico defa= ult (ex. int, float, + char, java.lang.String, java.util.Date, java.lang.= Integer, java.sql.Clob). + + + + + O nome da classe Java serializable + + + + + O nome da classe de um tipo customizado (ex. com.illflow.type.MyCustomType). + + + + + + Se voc=C3=AA n=C3=A3o especificar um tipo, o Hibernate ira= utilizar reflex=C3=A3o sobre a = + propriedade nomeada para ter uma id=C3=A9ia do tipo Hibern= ate correto. O Hibernate ira = + tentar interpretar o nome da classe retornada, usando as r= egras 2, 3 e 4 nesta ordem. = + Entretanto, isto n=C3=A3o =C3=A9 sempre suficiente Em cert= os casos, voc=C3=AA ainda ir=C3=A1 necessitar + do atributo type. (Por exemplo, para di= stinguir entre = + Hibernate.DATE ou Hibernate.TI= MESTAMP, = + ou para espcificar uma tipo ciustomizado.) + + = + + O atributo access permite voce controla= r como o Hibernate ir=C3=A1 = + acessar a propriedade em tempo de execu=C3=A7=C3=A3o. Por = default, o Hibernate ir=C3=A1 chamar os = + m=C3=A9todos get/set da propriedades. Se voce especificar = access=3D"field", = + o Hibernate ira bipassar os metodos get/set, acessnado o c= ampo diretamente, = + usando reflex=C3=A3o. Voc epode especificar sua pr=C3=B3pr= ia estrat=C3=A9gia para acesso da = + propriedade criando uma classe que implemente a interface = + org.hibernate.property.PropertyAccessor. + + + + Um recurso especialmente poderoso =C3=A9 o de propriedades= derivadas. Estas propriedades = + s=C3=A3o por defini=C3=A7=C3=A3o read-only, e o valor da p= ropriedade =C3=A9 calculado em tempo de execu=C3=A7=C3=A3o. = + Voc=C3=AA declara este calculo como uma express=C3=A3o SQL= , que traduz para clausula = + SELECT de uma subquery daquery SQL que = carrega a instancia: = + + + ]]> + + + Observe que voc=C3=AA pode referenciar as entidades da pr= =C3=B3pria tabela, = + atrav=C3=A9s da n=C3=A3o declara=C3=A7=C3=A3o de um alias = para uma coluna particular ( + customerId no exemplo dado). Observe ta= mbem que voce pode usar o = + mapeamento de elemento aninhado <formula>, se voc=C3=AA n=C3=A3o = + gostar de usar o atributo. + + + + + + many-to-one + + + Uma associa=C3=A7=C3=A3o ordin=C3=A1ria para outra classe = persistente =C3=A9 declarada usando o = + elemento many-to-one. O modelo relacion= al =C3=A9 uma = + associa=C3=A7=C3=A3o many-to-one: a uma chave estrangeira = de uma tabela referenciando + a chave primaria da tabela destino. + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + name: O nome da propriedade. + = + = + + + column (opcional): O nome d= a coluna foreign key. Isto = + pode tamb=C3=A9m ser especificado atrav=C3=A9s= de elementos aninhados = + <column>. + + + + + class (opcional =E2=80=93 d= efault para o tipo de propriedade = + determinado pela reflex=C3=A3o). O nome da cla= sse associada. = + + + + + cascade (opcional): Especif= ica quais opera=C3=A7=C3=B5es dever = + ser em cascata do objeto pai para o objeto ass= ociado. = + = + + + + fetch (opcional - default p= ara select): = + Escolhe entre recupera=C3=A7=C3=A3o outer-join= ou recupera=C3=A7=C3=A3o seq=C3=BCencial. + = + + + + update, insert (opcional - = valor default true): + especifica que as colunas mapeadas dever ser i= ncluidas em instru=C3=A7=C3=B5es SQL de = + UPDATE e/ou INSERT= . Setando ambas para = + false voc=C3=AA permite uma= associa=C3=A7=C3=A3o "derivada" pura cujos valores = + s=C3=A3o inicializados de algumas outras propr= iedades que mapeiam a mesma coluna ou = + por uma trigger ou outra aplica=C3=A7=C3=A3o. = + = + + + + property-ref: (opcional) O = nome da propriedade da classe associada = + que faz a jun=C3=A7=C3=A3o desta foreign key. = Se n=C3=A3o especificada, a chave primaria da = + classe associada ser=C3=A1 utilizada. = + = + = + + + access (opcional - valor de= fault property): A = + estrategia que o Hibernate deve utilizar para = acessar o valor da propriedade. + + + + + unique (opcional): Habilita= a gera=C3=A7=C3=A3o DDL de uma constraint = + unique para a coluna foreign-key. Alem disso, = permite ser o alvo de uma = + property-ref. Isso torna a = associa=C3=A7=C3=A3o multipla = + efetivamente um para um. = + + + + + not-null (opcional): Habili= ta a gera=C3=A7=C3=A3o DDL de uma constraint de = + nulidade para as foreign keys. + + + + + optimistic-lock (opcional -= valor default true): = + Especifica se mudan=C3=A7as desta propriedade = requerem ou n=C3=A3o travamento otimista. = + Em outras palavras, determina se um incremento= de vers=C3=A3o deve ocorrer quando = + esta propriedade est=C3=A1 suja. + + + + + lazy(opcional =E2=80=93 val= or default proxy): = + Por default, associa=C3=A7=C3=B5es de ponto un= ico s=C3=A3o envoltas em um proxie. = + lazy=3D"no-proxy" especific= a que a propriedade deve ser = + trazida de forma tardia quando a instancia da = vari=C3=A1vel =C3=A9 acessada pela = + primeira vez (requer instrumenta=C3=A7=C3=A3o = bytecode em tempo de cria=C3=A7=C3=A3o) = + lazy=3D"false" especifica q= ue a associa=C3=A7=C3=A3o ser=C3=A1 = + sempre recuperada fortemente. = + + + + + not-found (opcional - valor= default exception): = + Especifica como as foreign keys que referencia= m linhas ausentes ser=C3=A3o tratadas: + ignore ir=C3=A1 tratar a li= nha ausente como ama associa=C3=A7=C3=A7ao de null + + + + + entity-name (opcional): O n= ome da entidade da classe associada. = + = + + + + + formula (optional): Uma exp= ress=C3=A3o SQL que define um valor + para um foreign key computed. + + + + + + Setar o valor do atributo cascade para= qualquer valor = + significativo diferente de none ir=C3= =A1 propagar certas opera=C3=A7=C3=B5es = + ao objeto associado. Os valores significativos s=C3=A3o os= nomes das opera=C3=A7=C3=B5es b=C3=A1sicas = + do Hibernate, persist, merge, delete, save-update= , evict, replicate, lock, + refresh, assim como os valores especiais delete-orphan = + e all e combina=C3=A7=C3=B5es de nomes = de opera=C3=A7=C3=B5es separadas por v=C3=ADrgula, = + como por exemplo, cascade=3D"persist,merge,evict"= ou + cascade=3D"all,delete-orphan". Veja a s= e=C3=A7=C3=A3o = + para uma explic= a=C3=A7=C3=A3o completa. Note que = + associa=C3=A7=C3=B5es valoradas simples (associa=C3=A7=C3= =B5es muitos-pra-um, e um-pra-um) n=C3=A3o suportam = + orphan delete. + + = + + Uma t=C3=ADpica declara=C3=A7=C3=A3o muitos-pra-u= m se parece com esta: + + + ]]> + = + + O atributo property-ref deve apenas ser= usado para mapear dados = + legados onde uma chave estrangeira se referencia a uma cha= ve exclusiva da tabela = + associada que n=C3=A3o seja =C3=A0 chave prim=C3=A1ria. Es= te =C3=A9 um modelo relacional desagrad=C3=A1vel. = + Por exemplo, suponha que a classe Product tenha um n=C3=BAmero = + seq=C3=BCencial exclusivo, que n=C3=A3o =C3=A9 a chave pri= m=C3=A1ria. (O atributo unique = + controla a gera=C3=A7=C3=A3o de DDL do Hibernate com a fer= ramenta SchemaExport.) + + = + ]]> + = + + Ent=C3=A3o o mapeamento para OrderItem = poderia usar: + + = + ]]> + = + + Por=C3=A9m, isto obviamente n=C3=A3o =C3=A9 indicado, nunc= a. + + = + + Se a chave exclusiva referenciada engloba m=C3=BAltiplas p= ropriedades da entidade associada, = + voc=C3=AA deve mapear as propriedades referenciadas dentro= de um elemento chamado = + <properties> + + + = + + Se a chave exclusiva referenciada =C3=A9 a propriedade de um = componente, voc=C3=AA pode especificar = + um caminho para a propriedade. = + + = + ]]> = + = + + + + one-to-one (um-pra-um) + + + Uma associa=C3=A7=C3=A3o um-pra-um para outra classe persi= stente =C3=A9 declarada usando = + um elemento one-to-one . + + = + + + + + + + + + + + + + + ]]> + + + + name: O nome da propriedade. + = + = + + + class (opcional =E2=80=93 d= efault para o tipo da propriedade = + definido via reflection): O nome da classe ass= ociada. + = + + + + cascade (opcional): Especif= ica qual opera=C3=A7=C3=A3o deve = + ser cascateada do objeto pai para o objeto ass= ociado. + + + + + constrained (opcional): Esp= ecifica que uma chave estrangeira = + constraint na chave prim=C3=A1ria da tabela ma= peada referencia a tabela da classe = + associada, Esta op=C3=A7=C3=A3o afeta a ordem = em queh save() e + delete() s=C3=A3o cascatead= as, e determina se a associa=C3=A7=C3=A3o = + pode ser substitu=C3=ADda (isto tamb=C3=A9m = =C3=A9 usado pela ferramenta schema export). + = + + + + fetch ((opcional =E2=80=93 = valor default select): = + Escolhe entre outer-join fetching ou sequentia= l select fetching. + = + + + + property-ref(opcional): O n= ome da propriedade da classe associada = + que =C3=A9 ligada a chave prim=C3=A1ria desta = classe. Se n=C3=A3o for especificada, a chave prim=C3=A1ria = + da classe associada =C3=A9 utilizada. + = + = + + + access (opcional - valor de= fault padr=C3=A3o property): = + A estrat=C3=A9gia que o Hibernate pode usar pa= ra acessar o valor da propriedade. + + + + + formula (opcional): Quase t= odas associa=C3=A7=C3=B5es um-pra-um mapeiam = + para a chave prim=C3=A1ria da entidade dona. N= o caso raro, que n=C3=A3o =C3=A9 o caso, voc=C3=AA = + pode especificar uma outra coluna, colunas ou = express=C3=B5es para juntar utilizando = + uma formula SQL. (Veja org.hibernate.= test.onetooneformula = + para exemplo). + + + + + lazy (opcional =E2=80=93 va= lor default proxy): = + Por default, associa=C3=A7=C3=B5es single poin= t s=C3=A3o proxied. lazy=3D"no-proxy" = + especifica que a propriedade deve ser fetched = lazily quando o atributo =C3=A9 acessado = + pela primeira vez (requer build-time bytecode = instrumentation). = + lazy=3D"false" especifica q= ue a associa=C3=A7=C3=A3o vai sempre ser = + avidamente fetched. Note que se constrained=3D"false", = + proxing =C3=A9 imposs=C3=ADvel e o Hibernate v= ai =C3=A1vido fetch a associa=C3=A7=C3=A3o! + + + + + entity-name (opcional): O n= ome da entidade da classe associada. + = + + + + = + + Existem duas variedades de associa=C3=A7=C3=B5es um-pra-um: + + + + associa=C3=A7=C3=B5es de chave prim=C3=A1ria + + + associa=C3=A7=C3=B5es de chave estrangeira exclusiva + + + = + + Associa=C3=A7=C3=B5es de chave prim=C3=A1ria n=C3=A3o nece= ssitam de uma coluna extra de tabela; se duas = + linhas s=C3=A3o relacionadas pela associa=C3=A7=C3=A3o ent= =C3=A3o as duas linhas da tabela dividem a mesmo = + valor da chave prim=C3=A1ria. Assim, se voc=C3=AA quer que= dois objetos sejam relacionados por = + uma associa=C3=A7=C3=A3o de chave prim=C3=A1ria, voc=C3=AA= deve ter certeza que eles s=C3=A3o assinados com o = + mesmo valor identificador! + + = + + Para uma associa=C3=A7=C3=A3o de chave prim=C3=A1ria, adic= ione os seguintes mapeamentos em = + Employee e Person, r= espectivamente. + + + ]]> + ]]> + + + Agora n=C3=B3s devemos assegurar que as chaves prim=C3=A1r= ias de linhas relacionadas nas = + tabelas PERSON e EMPLOYEE s=C3=A3o iguais. N=C3=B3s usamos= uma estrat=C3=A9gia especial de gera=C3=A7=C3=A3o = + de identificador do Hibernate chamada foreign: + + + + + + employee + + + ... + +]]> + + + Uma nova inst=C3=A2ncia de Person salva= recentemente =C3=A9 ent=C3=A3o assinada = + com o mesmo valor da chave prim=C3=A1ria da inst=C3=A2ncia= de employee referenciada = + com a propriedade employee daquela Person. + + + + Alternativamente, uma chave estrangeira com uma unique con= straint, de = + Employee para Person= , pode ser expressa como: + + = + ]]> + = + + E esta associa=C3=A7=C3=A3o pode ser feita de forma bi-dir= ecional adicionando o seguinte = + no mapeamento de Person: + + = + ]]> + + + + + natural-id + + + + + ...... +]]> + + + Embora n=C3=B3s recomendemos o uso de surrogate keys como = chaves prim=C3=A1rias, voc=C3=AA deve = + ainda identificar chaves naturais para todas as entidades.= Uma chave natural =C3=A9 = + uma propriedade ou combina=C3=A7=C3=A3o de propriedades qu= e =C3=A9 exclusiva e n=C3=A3o nula. Se n=C3=A3o = + pude ser modificada, melhor ainda. Mapeie as propriedades = da chave natural dentro do = + elemento <natural-id>. O Hibernat= e ir=C3=A1 gerar a chave = + exclusiva necess=C3=A1ria e as constraints de nullability = , e seu mapeamento ser=C3=A1 = + apropriadamente auto documentado. + + = + + N=C3=B3s recomendamos com enfase que voc=C3=AA implemente = equals() e = + hashCode() para comparar as propriedade= s da chave natural da = + entidade. + + + + Este mapeamento n=C3=A3o tem o objetivo de uso com entidad= es com natural chaves prim=C3=A1rias. + + + + + + mutable mutable (opcional, val= or defaultfalse): = + Por default, propriedades naturais identificadoras= s=C3=A3o consideradas imut=C3=A1veis (constante). + + + + = + + = + + componente, componente din=C3=A2mico + + + O elemento<component> mapeia prop= riedades de um = + objeto filho para colunas da tabela de uma classe pai. Com= ponentes podem, = + um ap=C3=B3s o outro, declarar suas pr=C3=B3prias propried= ades, componentes ou cole=C3=A7=C3=B5es. = + Veja "Components" abaixo. + + + + + + + + + + + + + = + + = + + + ........ +]]> + + + + name: O nome da propriedade. + = + = + + + class (opcional =E2=80=93 v= alor default para o tipo de = + propriedade determinada por reflection): O nom= e da classe (filha) do = + componente. + = + + + + insert: As colunas mapeadas= aparecem nos = + SQL de INSERTs? + = + = + + + update: As colunas mapeadas= aparecem nos = + SQL de UPDATEs? + = + = + + + access (opcional =E2=80=93 = valor default property): = + A estrat=C3=A9gia que o Hibernate pode usar pa= ra acessar o valor da propriedade. + + + + + lazy (opcional - valor defa= ult false): = + Especifica que este componente deve ser fetche= d lazily quando o atributo for = + acessado pela primeira vez (requer build-time = bytecode instrumentation). + + + + + optimistic-lock (opcion= al =E2=80=93 valor default true): = + Especifica que atualiza=C3=A7=C3=B5es para= este componente requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o = + de um lock otimista. Em outras palavras, d= etermina se uma vers=C3=A3o de incremento deve = + ocorrer quando esta propriedade estiver mo= dificada. + + + + + unique (opcional =E2=80= =93 valor default false): = + Especifica que existe uma unique constrain= t em todas as colunas mapeadas do = + componente. + + + + + + + A tag filha <property> acrescenta= a propriedade + de mapeamento da classe filha para colunas de uma tabela. + + + + O elemento <component> permite um= sub-elemento = + <parent> mapeie uma propriedade d= a classe do componente = + como uma referencia de volta para a entidade que o cont=C3= =A9m. + + + + O elemento <dynamic-component> p= ermite que um = + Map possa ser mapeado como um component= e onde os nomes das = + propriedades referem-se para as chaves no mapa, veja = + . + + = + + + + propriedades + + + O elemento <properties> permite a= defini=C3=A7=C3=A3o de um grupo = + com nome, l=C3=B3gico de propriedades de uma classe. O uso= mais importante do construtor = + =C3=A9 que este permite uma combina=C3=A7=C3=A3o de propri= edades para ser o objetivo de uma = + property-ref. =C3=89 tamb=C3=A9m um mod= o conveninente para definir uma = + unique constraint de m=C3=BAltiplas colunas. + + + + + + + + + + = + + = + + + ........ +]]> + + + + name:: O nome l=C3=B3gico d= o agrupamento =E2=80=93 = + n=C3=A3o =C3=A9 o nome a= tual de propriedade. + = + = + + + insert: As colunas mapeadas= aparecem nos = + SQL de INSERTs? + = + = + + + update: As colunas mapeadas= aparecem nos = + SQL de UPDATEs? + = + = + + + optimistic-lock (opcion= al =E2=80=93 valor default true): = + Especifica que atualiza=C3=A7=C3=B5es para= estes componentes requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o de um + lock otimista. Em outras palavras, determi= na se uma vers=C3=A3o de incremento deve ocorrer = + quando estas propriedades estiverem modifi= cadas. + + + + + unique (opcional =E2=80= =93 valor defautl false): = + Especifica que uma unique constraint exist= e em todas as colunas mapeadas do componente. + + + + + = + + Por exemplo, se n=C3=B3s temos o seguinte mapeamento de <properties>: + + = + + + ... + + + + + +]]> + + + Ent=C3=A3o n=C3=B3s podemos ter uma associa=C3=A7=C3=A3o = de dados herdados que referem a esta chave = + exclusiva da tabela Person, ao inv=C3= =A9s de se referirem a chave = + prim=C3=A1ria: + + + + + + +]]> + = + + N=C3=B3s n=C3=A3o recomendamos o uso deste tipo de coisa f= ora do contexto de mapeamento de = + dados herdados. + + = + + + + subclass (subclasse) + + + Finalmente, a persist=C3=AAncia polim=C3=B3rfica requer a = declara=C3=A7=C3=A3o de cada subclasse = + da classe de persist=C3=AAncia raiz. Para a estrat=C3=A9gi= a de mapeamento = + table-per-class-hierarchy, a declara=C3=A7=C3=A3o <subclass> + deve ser usada. = + + = + + + + + + + + + + + ..... +]]> + + + + name: O nome de classe com= pletamente qualificada da subclasse. = + = + = + + + discriminator-value (opcion= al =E2=80=93 valor default o nome da classe): = + Um valor que distingue subclasses individuais. + = + + + + proxy (opcional): Especific= a a classe ou interface que = + usar=C3=A1 os proxies de inicializa=C3=A7=C3= =A3o atrasada. + = + + + + lazy (opcional, valor defau= lt true): = + Configurar lazy=3D"false" d= esabilitar=C3=A1 o uso de = + inicializa=C3=A7=C3=A3o atrasada. + + = + + + + Cada subclasse deve declarar suas pr=C3=B3prias propriedad= es persistentes e subclasses. = + As propriedades <version> e <id> = + s=C3=A3o configuradas para serem herdades da classe raiz. = Cada subclasse numa hierarquia = + deve definir um =C3=BAnico discriminator-value. Se nenhum for = + especificado, o nome da classe Java completamente qualific= ada ser=C3=A1 usada. + + = + + Para informa=C3=A7=C3=B5es sobre mapeamento de heran=C3=A7= as, veja o . + + + + + + joined-subclass + + + Alternativamente, cada subclasse pode ser mapeada para sua= pr=C3=B3pria tabela = + (Estrat=C3=A9gia de mapeamento table-per-subclass). O esta= do herdado =C3=A9 devolvido = + por associa=C3=A7=C3=A3o com a tabela da superclasse. N=C3= =B3s usamos o elemento = + <joined-subclass>. + + + + + + + + + + + + + + + ..... +]]> + + + + name: O nome da classe comp= letamente qualificada da = + subclasse. + = + = + + + table: O nome da tabela da = subclasse. + = + = + + + proxy (opcional): Especific= a a classe ou interface = + para usar os proxies de recupera=C3=A7=C3=A3o = atrasada. + = + + + + lazy (opcional, valor defau= lt true): = + Fixanr lazy=3D"false" desab= ilita o uso recupera=C3=A7=C3=A3o = + atrasada. + + = + + + + + A coluna discriminator requerida para esta estrat=C3=A9gia= de mapeamento. Por=C3=A9m, = + cada subclasse deve declarar uma coluna de tabela com o id= entificador do objeto = + usando o elemento <key>. O mapeam= ento no in=C3=ADcio do = + cap=C3=ADtulo poderia ser re-escrito assim: + + = + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + Para informa=C3=A7=C3=B5es de mapeamentos de heran=C3=A7a= , veja . + + + + + + union-subclass + + + Uma terceira op=C3=A7=C3=A3o =C3=A9 mapear para tabelas ape= nas as classes concretas de uma = + hierarquia de heran=C3=A7as, (a estrat=C3=A9gia table-per-c= oncrete-class) onde cada tabela = + define todos os estados persistentes da classe, incluindo e= stados herdados. = + No Hibernate, n=C3=A3o =C3=A9 absolutamente necess=C3=A1rio= mapear explicitamente como hierarquia = + de heran=C3=A7as. Voc=C3=AA pode simplesmente mapear cada c= lasse com uma declara=C3=A7=C3=A3o = + <class> separada. Por=C3=A9m, se v= oc=C3=AA deseja usar associa=C3=A7=C3=B5es = + polim=C3=B3rficas (por exemplo: uma associa=C3=A7=C3=A3o pa= ra a superclasse de sua hierarquia), = + voc=C3=AA precisa usar o mapeamento <union-subc= lass>. + + + + + + + + + + + + + + ..... +]]> + + + + name: O nome da subclasse c= ompletamente qualificada. + = + = + + + table: O nome da tabela da = subclasse. + = + = + + + proxy (optional): Specifies= a class or interface to use = + for lazy initializing proxies. + = + proxy (opcional): Especific= a a classe ou interface para usar = + os proxies de recupera=C3=A7=C3=A3o atrasada. + = + + + + lazy (optional, defaults to= true): Setting = + lazy=3D"false" disables the= use of lazy fetching. + lazy (opcional, valor defau= lt ptrue): = + Fixando lazy=3D"false" desa= bilita o uso da recupera=C3=A7=C3=A3o atrasada. + + + + + + + A coluna discriminat=C3=B5ria n=C3=A3o =C3=A9 requerida pa= ra esta estrat=C3=A9gia de mapeamento. + + + + + Para informa=C3=A7=C3=B5es sobre mapeamentos de heran=C3= =A7a, veja . + + + + + + join + + + Usando o elemento <join>>, =C3= =A9 poss=C3=ADvel mapear = + propriedades de uma classe para v=C3=A1rias tabelas. + + + + + + + + + + + + + = + + = + + ... +]]> + + + + + table: O nome da tabela ass= ociada. + + + + + schema (opcional): Sobrep= =C3=B5e o nome do esquema = + especificado pelo elemento raiz <h= ibernate-mapping>. + + + + + catalog (opcional): Sobrep= =C3=B5e o nome do cat=C3=A1logo + especificado pelo elemento raiz<hi= bernate-mapping>. + + + + + fetch(opcional =E2=80=93 va= lor default join): Se setado = + para join, o padr=C3=A3o, o= Hibernate ir=C3=A1 usar um inner join para = + restaurar um join definido = por uma classe ou suas subclasses e = + uma outer join para um join= definido por uma subclasse. = + Se setado para select, ent= =C3=A3o o Hibernate ir=C3=A1 usar uma sele=C3=A7=C3=A3o = + seq=C3=BCencial para um <join><= /literal> definida numa subclasse, que ir=C3=A1 = + ser emitido apenas se uma linha se concentrar = para representar uma inst=C3=A2ncia = + da subclasse. Inner joins ir=C3=A1 ainda ser u= sado para restaurar um = + <join> definido pela = classe e suas superclasses. + + + + + inverse (opcional =E2=80=93= valor default false): = + Se habilitado, o Hibernate n=C3=A3o ir=C3=A1 t= entar inserir ou atualizar as propriedades = + definidas por este join. + + + + + optional (opcional =E2=80= =93 valor default false): + Se habilitado, o Hibernate ir=C3=A1 inserir um= a linha apenas se as propriedades definidas = + por esta jun=C3=A7=C3=A3o n=C3=A3o forem nulas= e ir=C3=A1 sempre usar uma outer join para = + recuperar as propriedades. + + + + + + + Por exemplo, a informa=C3=A7=C3=A3o de endere=C3=A7o para = uma pessoa pode ser mapeada para uma = + tabela separada (enquanto preservando o valor da sem=C3=A2= ntica de tipos para = + todas as propriedades): = + + + + + ... + + + + + + + + ...]]> + + + Esta caracter=C3=ADstica =C3=A9 =C3=BAtil apenas para mode= los de dados legados, n=C3=B3s recomendamos = + menos tabelas do que classes e um modelo de dom=C3=ADnio b= em granulado. Por=C3=A9m, =C3=A9 = + =C3=BAtil para ficar trocando entre estrat=C3=A9gias de ma= peamento de heran=C3=A7a = + numa hierarquia simples, como explicado mais a frente. + + + + + + key + + + N=C3=B3s vimos que o elemento <key> surgiu algumas vezes + at=C3=A9 agora. Ele aparece em qualquer lugar que o elemen= to pai define uma jun=C3=A7=C3=A3o = + para a nova tabela, e define a chave estrangeira para a ta= bela associada, que = + referencia a chave prim=C3=A1ria da tabela original. = = + + + + + + + + + + + + ]]> + + + + . + column (opcional): O nome d= a coluna da chave estrangeira. = + Isto tamb=C3=A9m pode ser especificado por ani= nhamento de elemento(s) = + <column>. + + + + + on-delete (opcional, valor = default noaction): = + Especifica se a constraint da chave estrangeir= a no banco de dados esta + habilitada para cascade delete . + + + + + property-ref (opcional): Es= pecifica que a chave estrangeira = + se refere a colunas que n=C3=A3o s=C3=A3o chav= e prim=C3=A1ria da tabela original. = + (Util para base de dados legadas.) + + + + + not-null (opcional): Especi= fica que a coluna da chave = + estrangeira n=C3=A3o aceita valores nulos (ist= o =C3=A9 impl=C3=ADcito em qualquer momento = + que a chave estrangeira tamb=C3=A9m fizer part= e da chave prim=C3=A1ria). + + + + + update (optional): Specifie= s that the foreign key should never + be updated (this is implied whenever the forei= gn key is also part of the primary = + key). + update (opcional): Especifi= ca que a chave estrangeira nunca = + deve ser atualizada (isto =C3=A9 impl=C3=ADcit= o em qualquer momento que a chave estrangeira = + tamb=C3=A9m fizer parte da chave prim=C3=A1ria= ). + + + + + unique (opcional): Especif= ica que a chave estrangeira deve ter = + uma constraint unique (sto =C3=A9 impl=C3=ADci= to em qualquer momento que a chave estrangeira = + tamb=C3=A9m fizer parte da chave prim=C3=A1ria= ). + + + + + + + N=C3=B3s recomendamos que para sistemas que a performance = de delete seja importante, todas as = + chaves deve ser definida on-delete=3D"cascade", e o Hibernate ir=C3=A1 usar = + uma constraint a n=C3=ADvel de banco de dados ON = CASCADE DELETE, ao inv=C3=A9s = + de muitas instru=C3=A7=C3=B5es DELETE. = Esteja ciente que esta caracter=C3=ADstica =C3=A9 = + um atalho da estrat=C3=A9gia usual de optimistic locking d= o Hibernate para dados versionados. + + = + + Os atributos not-null e update= s=C3=A3o =C3=BAteis quando = + estamos mapeamos uma associa=C3=A7=C3=A3o unidirecional um= para muitos. Se voc=C3=AA mapear uma = + asocia=C3=A7=C3=A3o unidirecional um para muitos para uma = chave estrangeira non-nullable, voc=C3=AA = + deve declarar a coluna chave usando = + <key not-null=3D"true">. + + + + + + elementos column e formula + + Qualquer elemento de mapeamente que aceita um atributo column ir=C3=A1 = + aceitar alternativamente um subelemento <column= >. Da mesma forma, = + formula =C3=A9 uma alternativa para o at= ributo formula. = + + + ]]> + + SQL expression]]><= /programlisting> + = + + O atributo column e formula podem at=C3=A9 ser combinados + dentro da mesma propriedade ou associa=C3=A7=C3=A3o mapean= do para expressar, = + por exemplo, associa=C3=A7=C3=B5es ex=C3=B3ticas. + + + + + 'MAILING' +]]> + + = + = + + import + + + Suponha que a sua aplica=C3=A7=C3=A3o tem duas classes per= sistentes com o mesmo nome, e voc=C3=AA n=C3=A3o quer = + especificar o nome qualificado (do pacote) nas queries do = Hibernate. As Classes devem = + ser "importadas" explicitamente, de prefer=C3=AAncia conta= ndo com auto-import=3D"true". = + Voc=C3=AA pode at=C3=A9 importar classes e interfaces que = n=C3=A3o est=C3=A3o explicitamente mapeadas. + + = + ]]> + = + + + + + + ]]> + + + + class: O nome qualificado (= do pacote) de qualquer classe Java. + = + = + + + rename (opcional =E2=80=93 = valor default, o nome da classe n=C3=A3o = + qualificada): Um nome que pode ser usado numa = linguagem de consulta. + = + + + + = + + = + + any + = + + Existe mais um tipo de propriedade de mapeamento. O elemen= to de mapeamento = + <any> define uma associa=C3=A7=C3= =A3o polim=C3=B3rfica para classes de m=C3=BAltiplas tabelas. = + Este tipo de mapeamento sempre requer mais de uma coluna. = A primeira coluna possui o tipo da entidade = + associada. A outra coluna que ficou possui o identificador= . =C3=89 imposs=C3=ADvel especificar uma restri=C3=A7=C3=A3o = + de chave estrangeira para este tipo de associa=C3=A7=C3=A3= o, assim isto claramente n=C3=A3o =C3=A9 visto = + como um caminho usual para associa=C3=A7=C3=B5es (polim=C3= =B3rficas) de mapeamento. Voc=C3=AA deve usar este mapeamento + apenas em casos muito especiais (exemplo: audit logs, dado= s de sess=C3=A3o do usu=C3=A1rio, etc). + + + + + O atributo meta-type permite a aplica= =C3=A7=C3=A3o especificar um tipo adaptado = + que mapeia valores de colunas de banco de dados para clas= ses persistentes que tem propriedades = + identificadoras do tipo especificado atrav=C3=A9s do id-type. Voc=C3=AA deve especificar = + o mapeamento de valores do meta-type para nome de classes. + + + + + + + + +]]> + + + + + + + + + + + + + + ..... + + + ..... +]]> + + + + name: o nome da propriedade. + = + = + + + id-type: o tipo identificad= or. + = + = + + + meta-type (opcional =E2=80= =93 valor default string): = + Qualquer tipo que =C3=A9 permitido para um map= eamento discriminador. + = + = + + + cascade (opcional =E2=80=93= valor default none): = + o estilo do cascade. + = + = + + + access (opcional =E2=80=93 = valor default property): = + A estrat=C3=A9gia que o hibernate deve usar pa= ra acessar o valor da propriedade. + + + + + optimistic-lock (opcional -= valor defaulttrue): = + Especifica que as atualiza=C3=A7=C3=B5es para = esta propriedade requerem ou n=C3=A3o aquisi=C3=A7=C3=A3o da = + trava otimista. Em outras palavras, define se = uma vers=C3=A3o de incremento deve ocorrer = + se esta propriedade est=C3=A1 modificada. + + + + + + + + + + + Tipos do Hibernate + + + Entidades e valores + + + Para entender o comportamento de v=C3=A1rios objetos em n= =C3=ADvel de linguagem de Java a = + respeito do servi=C3=A7o de persist=C3=AAncia, n=C3=B3s pr= ecisamos classific=C3=A1-los em dois grupos. + + + + Uma entidade existe independentement= e de qualquer outro = + objeto guardando refer=C3=AAncias para a entidade. Em cont= raste com o modelo usual de = + Java que um objeto n=C3=A3o referenciado =C3=A9 coletado p= elo garbage collector. Entidades = + devem ser explicitamente salvas ou deletada (exceto em ope= ra=C3=A7=C3=B5es de salvamento = + ou dele=C3=A7=C3=A3o que possam ser executada em cascata de uma entidade = + pai para seus filhos). Isto =C3=A9 diferente do modelo ODM= G de persist=C3=AAncia do objeto = + por acessibilidade =E2=80=93 e corresponde quase a como ob= jetos de aplica=C3=A7=C3=B5es s=C3=A3o = + geralmente usados em grandes sistemas. Entidades suportam = refer=C3=AAncias circulares = + e comuns. Eles podem ser versionadas. + + + + Uma entidade em estado persistente consiste de refer=C3=AA= ncias para outras entidades = + e inst=C3=A2ncias de tipos de valor.= Valores s=C3=A3o primitivos, = + cole=C3=A7=C3=B5es (n=C3=A3o o que tem dentro de uma cole= =C3=A7=C3=A3o), componentes e certos objetos = + imut=C3=A1veis. Entidades distintas, valores (em cole=C3= =A7=C3=B5es e componentes particulares) + s=C3=A3o persistidos e apagados por = acessibilidade. Visto que = + objetos value (e primitivos) s=C3=A3o persistidos e apagad= os junto com as entidades = + que os cont=C3=A9m e n=C3=A3o podem ser versionados indepe= ndentemente. Valores t=C3=AAm = + identidade n=C3=A3o independente, assim eles n=C3=A3o pode= m ser comuns para duas = + entidades ou cole=C3=A7=C3=B5es. + + + + + At=C3=A9 agora, n=C3=B3s estivemos usando o termo "classe = persistente" para referir = + a entidades. N=C3=B3s iremos continuar a fazer isto. Falan= do a rigor, por=C3=A9m, nem todas = + as classes definidas pelo usu=C3=A1rio com estados persist= entes s=C3=A3o entidades. Um = + componente =C3=A9 uma classe de usu= =C3=A1rio definida com valores = + sem=C3=A2nticos. Uma propriedade de Java de tipo = java.lang.String = + tamb=C3=A9m tem um valor sem=C3=AAntico. Dada esta defini= =C3=A7=C3=A3o, n=C3=B3s podemos dizer que = + todos os tipos (classes) fornecida pelo JDK tem tipo de va= lor sem=C3=A2ntico em Java, = + enquanto que tipos definidos pelo usu=C3=A1rio pode ser ma= peados com entidade ou valor = + de tipo sem=C3=A2ntico. Esta decis=C3=A3o pertence ao dese= nvolvedor da aplica=C3=A7=C3=A3o. Uma boa = + dica para uma classe entidade em um modelo de dom=C3=ADnio= s=C3=A3o refer=C3=AAncias comuns = + para uma inst=C3=A2ncia simples daquela classe, enquanto a= composi=C3=A7=C3=A3o ou agrega=C3=A7=C3=A3o = + geralmente se traduz para um valor de tipo. + + + + N=C3=B3s iremos rever ambos os conceitos durante toda a do= cumenta=C3=A7=C3=A3o. + + + + + O desafio pe mapear o sistema de tipo de Java (e a defini= =C3=A7=C3=A3o do desenvolvedor de = + entidades e tipos de valor) para o sistema de tipo SQL/ban= co de dados. A ponte entre ambos = + os sistemas =C3=A9 fornecido pelo Hibernate: para entidade= s que usam = + <class>, <subclass>= ; e assim por diante. = + Para tipos de valores n=C3=B3s usamos <propert= y>, = + <component>, etc, geralmente com = um atributo = + type. O valor deste atributo =C3=A9 o n= ome de um tipo de = + mapeamento do Hibernate. O Hibernate fornece mu= itos mapeamentos = + (para tipos de valores do JDK padr=C3=A3o) ut of the box. = Voc=C3=AA pode escrever os seus = + pr=C3=B3prios tipos de mapeamentos e implementar sua estra= t=C3=A9gia de convers=C3=A3o adaptada, = + como voc=C3=AA ver=C3=A1 adiante. + + + + Todos os tipos internos do hibernate exceto cole=C3=A7=C3= =B5es suportam sem=C3=A2nticas nulas. + + + + + + + Valores de tipos b=C3=A1sicos + + + O tipos internos de mapeamentos b=C3=A1sicos podem ser a g= rosso modo categorizado como: + + + integer, long, short, float, double= , character, byte, + boolean, yes_no, true_false + + + Tipos de mapeamentos de classes primitivas= ou wrapper Java especificos + (vendor-specific) para tipos de coluna SQL= . Boolean, = + boolean, yes_no s=C3=A3= o todas codifica=C3=A7=C3=B5es alternativas = + para um boolean ou java.lang.Boolean + do Java. + + + + + string + + + Um tipo de mapeamento de java.lan= g.String para + VARCHAR (ou VA= RCHAR2 no Oracle). + + + + + date, time, timestamp + + + Tipos de mapeamento de java.util.= Date e suas = + subclasses para os tipos SQL DATE= , + TIME e TIMESTA= MP = + (ou equivalente). + + + + + calendar, calendar_date + + + Tipo de mapeamento de java.util.C= alendar para = + os tipos SQL TIMESTAMP = e = + DATE (ou equivalente). + + + + + big_decimal, big_integer<= /term> + + + Tipo de mapeamento de java.math.B= igDecimal and + java.math.BigInteger pa= ra NUMERIC + (ou NUMBER no Oracle). + + + + + locale, timezone, currency + + + Tipos de mapeamentos de java.util= .Locale, + java.util.TimeZone e java.util.Currency + para VARCHAR (ou VARCHAR2 no Oracle). = + Inst=C3=A2ncias de f Locale e Currency = + s=C3=A3o mapeados para seus c=C3=B3digos I= SO. Inst=C3=A2ncias de TimeZone = + s=C3=A3o mapeados para seu ID. + + + + + class + + + um tipo de mapeamento de java.lan= g.Class para = + VARCHAR (ou V= ARCHAR2 no = + Oracle). Uma Class =C3= =A9 mapeada pelo = + seu nome qualificado (completo). + + + + + binary + + + Mapeia arrays de bytes para um tipo bin=C3= =A1rio de SQL apropriado. + + + + + text + + + Maps long Java strings to a SQL C= LOB or = + TEXT type. + Mapeia strings longas de Java para um tipo= SQL + CLOB ou TEXT. + + + + + serializable + + + Mapeia tipos Java serializ=C3=A1veis para = um tipo bin=C3=A1rio SQL apropriado. = + Voc=C3=AA pode tamb=C3=A9m indicar o tipo = serializable do = + Hibernate com o nome da classe ou interfac= e Java serializ=C3=A1vel que = + n=C3=A3o =C3=A9 padr=C3=A3o para um tipo b= =C3=A1sico. + + + + + clob, blob + + + Tipos de mapeamentos para as classes JDBC = java.sql.Clob and + java.sql.Blob. Estes ti= pos podem ser inconveniente para = + algumas aplica=C3=A7=C3=B5es, visto que o = objeto blob ou clob pode n=C3=A3o ser reusado = + fora de uma transa=C3=A7=C3=A3o. (Al=C3=A9= m disso, o suporte de driver =C3=A9 imcompleto e = + inconsistente.) + + + + + + imm_date, imm_time, imm_timestamp, im= m_calendar, imm_calendar_date, + imm_serializable, imm_binary + + + + Mapeando tipos para o que geralmente s=C3= =A3o consideradas tipos mut=C3=A1veis de = + Java, onde o Hibernate faz determinadas ot= imiza=C3=A7=C3=B5es apropriadas somente = + para tipos imut=C3=A1veis de Java, e a apl= ica=C3=A7=C3=A3o trata o objeto como imut=C3=A1vel. = + Por exemplo, voc=C3=AA n=C3=A3o deve chama= r Date.setTime() para = + uma inst=C3=A2ncia mapeada como = imm_timestamp. Para mudar = + o valor da propriedade, e ter a mudan=C3= =A7a feita persistente, a aplica=C3=A7=C3=A3o = + deve atribuir um novo objeto (nonidentical= ) =C3=A0 propriedade. = + + + + + = + + + + Identificadores =C3=BAnicos das entidades e cole=C3=A7=C3= =B5es podem ser de qualquer tipo = + b=C3=A1sico exceto binary, blo= b ou = + clob. (Identificadores compostos tamb= =C3=A9m s=C3=A3o permitidos, = + veja abaixo.) + + = + + Os tipos de valores b=C3=A1sicos t=C3=AAm suas constantes= Type = + correspondentes definidas em org.hibernate.Hibern= ate. Por exemplo, + Hibernate.STRING representa o tipo string. = + + + + + + Tipos de valores personalizados + + + =C3=89 relativamente f=C3=A1cil para desenvolvedores criar= seus pr=C3=B3prios tipos de valor. = + Por exemplo, voc=C3=AA pode querer persistir propriedades = do tipo = + java.lang.BigInteger para colunas VARCHAR. O = + Hibernate n=C3=A3o fornece um tipo correspondente para iss= o. Mas os tipos adaptados = + n=C3=A3o s=C3=A3o limitados a mapeamento de uma propriedad= e (ou elemento de cole=C3=A7=C3=A3o) a uma = + =C3=BAnica coluna da tabela. Assim, por exemplo, voc=C3=AA= p=C3=B4de ter uma propriedade Java = + getName()/setName() = do tipo = + java.lang.String que =C3=A9 persistido = para colunas = + FIRST_NAME, INITIAL,= SURNAME. = + + + = + + Para implementar um tipo personalizado, implemente org.hibernate.UserType + or org.hibernate.CompositeUserType e de= clare propriedades usando o nome = + qualificado da classe do tipo. Veja org.hibernate= .test.DoubleStringType = + para ver o tipo das coisas que s=C3=A3o poss=C3=ADveis. = + + + + + +]]> + + + Observe o uso da tag <column> par= a mapear uma propriedade = + para colunas m=C3=BAltiplas. = + + = + + As interfaces CompositeUserType, EnhancedUserType, + UserCollectionType, e UserVers= ionType = + fornecem suporte para usos mais especializados. + + = + + Voc=C3=AA pode mesmo fornecer par=C3=A2metros a um UserType no arquivo de mapeamento. = + Para isto, seu UserType deve implementa= r a interface = + org.hibernate.usertype.ParameterizedType. Para fornecer par=C3=A2metros a seu = + tipo personalizado, voc=C3=AA pode usar o elemento <type> em seus = + arquivos de mapeamento. = + + = + + + 0 + +]]> + + + O UserType pode agora recuperar o valor= para o par=C3=A2metro chamado = + default da Propriedade do passado a ele. = + + = + + Se voc=C3=AA usar freq=C3=BCentemente um determinado UserType, pode ser =C3=BAtil definir = + um nome mais curto para ele. Voc=C3=AA pode fazer isto usa= ndo o elemento = + <typedef>. Typedefs atribui um no= me a um tipo personalizado, e pode tamb=C3=A9m = + conter uma lista de valores default de par=C3=A2metro se o= tipo for parametrizado. + + = + + 0 +]]> + + ]]> + + + It is also possible to override the parameters supplied in= a typedef on a case-by-case basis + by using type parameters on the property mapping. + + = + + Even though Hibernate's rich range of built-in types and s= upport for components means you + will very rarely need to use a custom= type, it is nevertheless + considered good form to use custom types for (non-entity) = classes that occur frequently + in your application. For example, a MonetaryAmoun= t class is a good + candidate for a CompositeUserType, even= though it could easily be mapped = + as a component. One motivation for this is abstraction. Wi= th a custom type, your mapping = + documents would be future-proofed against possible changes= in your way of representing = + monetary values. + + + + = + + + + Mapping a class more than once + + It is possible to provide more than one mapping for a particul= ar persistent class. In this + case you must specify an entity name do d= isambiguate between instances + of the two mapped entities. (By default, the entity name is th= e same as the class name.) + Hibernate lets you specify the entity name when working with p= ersistent objects, when writing + queries, or when mapping associations to the named entity. + + = + + ... + + + + + + + + ... + +]]> + + + Notice how associations are now specified using entit= y-name instead of + class. + + + + + + SQL quoted identifiers + + You may force Hibernate to quote an identifier in the gene= rated SQL by enclosing the table or + column name in backticks in the mapping document. Hibernat= e will use the correct quotation + style for the SQL Dialect (usually doub= le quotes, but brackets for SQL + Server and backticks for MySQL). + + + + <= /id> + + ... +]]> + + + + = + + Metadata alternatives + = + + XML isn't for everyone, and so there are some alternative ways to = define O/R mapping metadata in Hibernate. + + + + Using XDoclet markup + + + Many Hibernate users prefer to embed mapping information direc= tly in sourcecode using + XDoclet @hibernate.tags. We will not cover = this approach in this + document, since strictly it is considered part of XDoclet. How= ever, we include the + following example of the Cat class with XDo= clet mappings. + + + + + + See the Hibernate web site for more examples of XDoclet and Hi= bernate. + + + + + + Using JDK 5.0 Annotations + + + JDK 5.0 introduced XDoclet-style annotations at the language l= evel, type-safe and + checked at compile time. This mechnism is more powerful than X= Doclet annotations and + better supported by tools and IDEs. IntelliJ IDEA, for example= , supports auto-completion + and syntax highlighting of JDK 5.0 annotations. The new revisi= on of the EJB specification + (JSR-220) uses JDK 5.0 annotations as the primary metadata mec= hanism for entity beans. + Hibernate3 implements the EntityManager of = JSR-220 (the persistence API), + support for mapping metadata is available via the Hi= bernate Annotations + package, as a separate download. Both EJB3 (JSR-220) and Hiber= nate3 metadata is supported. + + + + This is an example of a POJO class annotated as an EJB entity = bean: + + + orders; + + // Getter/setter and business methods +}]]> + + + Note that support for JDK 5.0 Annotations (and JSR-220) is sti= ll work in progress and + not completed. Please refer to the Hibernate Annotations modul= e for more details. + + = + + + + + Generated Properties + + Generated properties are properties which have their values ge= nerated by the + database. Typically, Hibernate applications needed to refresh + objects which contain any properties for which the database wa= s generating values. + Marking properties as generated, however, lets the application= delegate this + responsibility to Hibernate. Essentially, whenever Hibernate = issues an SQL INSERT + or UPDATE for an entity which has defined generated properties= , it immediately + issues a select afterwards to retrieve the generated values. + + + Properties marked as generated must additionally be non-insert= able and non-updateable. + Only versions, + timestamps, and + simple properti= es can be marked as + generated. + + + never (the default) - means that the given proper= ty value + is not generated within the database. + + + insert - states that the given property value is = generated on + insert, but is not regenerated on subsequent updates. Things like c= reated-date would + fall into this category. Note that even thought + version and + timestamp pro= perties can + be marked as generated, this option is not available there... + + + always - states that the property value is genera= ted both + on insert and on update. + + + + + Auxiliary Database Objects + + Allows CREATE and DROP of arbitrary database objects, in conju= nction with + Hibernate's schema evolution tools, to provide the ability to = fully define + a user schema within the Hibernate mapping files. Although de= signed specifically + for creating and dropping things like triggers or stored proce= dures, really any + SQL command that can be run via a java.sql.Statement.= execute() + method is valid here (ALTERs, INSERTS, etc). There are essent= ially two modes for + defining auxiliary database objects... + + + The first mode is to explicitly list the CREATE and DROP comma= nds out in the mapping + file: + + + ... + + CREATE TRIGGER my_trigger ... + DROP TRIGGER my_trigger + +]]> + + The second mode is to supply a custom class which knows how to= construct the + CREATE and DROP commands. This custom class must implement the + org.hibernate.mapping.AuxiliaryDatabaseObject interface. + + + ... + + + +]]> + + Additionally, these database objects can be optionally scoped = such that they only + apply when certain dialects are used. + + + ... + + + + + +]]> + + + Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ba= tch.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xm= l 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/batch.xm= l 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,360 +1,364 @@ = -=EF=BB=BF=EF=BB=BF - Processamento de lotes - = - - Uma alternativa para inserir 100.000 linhas no banco de dados usan= do o Hibernate = - pode ser a seguinte: = - - - - - - Isto ir=C3=A1 falhar em algum lugar pr=C3=B3ximo a linha 50.000, l= an=C3=A7ando uma = - OutOfMemoryException. Isso ocorre devido ao fat= o do Hibernate = - fazer cache de todas as inst=C3=A2ncias de Customer inseridas num = - cach=C3=AA em n=C3=ADvel de sess=C3=A3o. - - - - Neste cap=C3=ADtulo veremos como contornar esse problema. Entreta= nto, se voc=C3=AA vai realizar = - processamento de lotes, =C3=A9 muito importante que voc=C3=AA habi= lite o uso de lotes JDBC, se = - voc=C3=AA pretende obter um desempenho razo=C3=A1vel. Defina o tam= anho do lote JDBC em um = - valor razo=C3=A1vel (algo entre 10-50): - - = - - - - Voc=C3=AA tamb=C3=A9m pode querer rodar esse tipo de processamento= de lotes com o cache = - secund=C3=A1rio completamente desabilitado: - - - - - - Mas isto n=C3=A3o =C3=A9 absolutamente necess=C3=A1rio, desde que = n=C3=B3s possamos ajustar o = - CacheMode para desabilitar a intera=C3=A7=C3= =A3o com o cache secund=C3=A1rio. - - - - Inser=C3=A7=C3=A3o de lotes - - - Quando voc=C3=AA estiver inserindo novos objetos persistentes,= voc=C3=AAs deve executar = - os m=C3=A9todos flush() e clear()= regularmente - na sess=C3=A3o, para controlar o tamanho do cache prim=C3=A1ri= o. = - - - - - - - - Batch updates - - - Para recuperar e atualizar informa=C3=A7=C3=B5es a mesma id=C3= =A9ia =C3=A9 v=C3=A1lida. Adicionalmente, = - pode precisar usar o scroll() para usar re= cursos no lado = - do servidor em queries que retornam muita informa=C3=A7=C3=A3o= . = - - - - - - = - - A interface StatelessSession - - Alternativamente, o Hibernate prov=C3=AA uma API orientada =C3= =A0 comandos, usada para = - transmitir um fluxo de dados de e para o banco de dados na for= ma de objetos soltos. = - Uma StatelessSession n=C3=A3o tem um conte= xto persistente associado e = - n=C3=A3o fornece muito das sem=C3=A2nticas de alto n=C3=ADvel = para controle do ciclo de vida. = - Em especial, uma StatelessSession n=C3=A3o implemente o cache = prim=C3=A1rio e nem interage = - com o cache secund=C3=A1rio ou query cache. Ele n=C3=A3o imple= menta salvamento transacional = - automatico ou checagem autom=C3=A1tica de mudan=C3=A7as. Opera= =C3=A7=C3=A3o realizadas usando uma = - StatelessSession n=C3=A3o fazem nenhum tipo de cascade com as = instancias associadas. = - As cole=C3=A7=C3=B5es s=C3=A3o ignoradas por uma StatelessSess= ion. Opera=C3=A7=C3=B5es realizadas com um = - StatelessSession ignoram a arquitetura de eventos e os interce= ptadores. = - StatelessSession s=C3=A3o vulner=C3=A1veis aos efeitos do alia= sing dos dados, devido a = - falta do cache prim=C3=A1rio. Uma StatelessSession =C3=A9 uma = abstra=C3=A7=C3=A3o de baixo n=C3=ADvel, = - muito mais pr=C3=B3xima do JDBC. = - - = - - - - Veja neste exempo, as instancias de Customer retornadas pela query = - s=C3=A3o imediatamente desvinculadas. Elas nunca ser=C3=A3o as= sossiadas =C3=A0 um contexto persistente. - - = - - As opera=C3=A7=C3=B5es insert(), update() e= delete() - definidos pela interface StatelessSession s= =C3=A3o considerados = - opera=C3=A7=C3=B5es diretas no banco de dados (row-level opera= tions), isso resulta em uma = - execu=C3=A7=C3=A3o imediata de comandos SQL INSERT, = UPDATE ou - DELETE respectivamente. Devido a isso, eles= possuem uma = - sem=C3=A2ntica bem diferente das opera=C3=A7=C3=B5es = save(), saveOrUpdate() = - ou delete() definidas na interface Session. - - - - - - Opera=C3=A7=C3=B5es no estilo DML - - - Como j=C3=A1 discutido, mapeamento objeto/relacional autom=C3= =A1tico e transparente =C3=A9 conseguido = - com a ger=C3=AAncia do estado do objeto. Com isto o estado daq= uele objeto fica dispon=C3=ADvel na = - mem=C3=B3ria, manipulando(usando as express=C3=B5es SQL Data Manipulation Language = - (SQL-style DML): INSERT, UPDATE, DELETE) = - os dados diretamente no banco de dados n=C3=A3o ir=C3=A1 afeta= r o estado registrado em mem=C3=B3ria. = - Entretanto, o Hibernate prov=C3=AA m=C3=A9todos para executar = queries SQL-style DML, que s=C3=A3o = - totalmente executas com HQL (Hibernate Query Language) = - (HQL). - - - - A pseudo-sintaxe para express=C3=B5es UPDATE e DELETE =C3=A9: = - ( UPDATE | DELETE ) FROM? NomeEntidade (WHERE condi= =C3=A7=C3=B5es_where)?. = - Algumas observa=C3=A7=C3=B5es: - - - - - - Na clausula from, a palavra chave FROM =C3=A9 opcional; - - - - - Somente uma entidade pode ser chamada na clausula from= ; opcionalmente pode ter - um alias. Se o nome da entidade for possuir um alias, = ent=C3=A3o qualquer propriedade = - referenciada deve usar esse alias qualificado; se o no= me da entidade n=C3=A3o possuir - um alias, ent=C3=A3o nenhuma das propriedade precisa u= sar o acesso qualificado. - - - - - Na joins (amba= s impl=C3=ADcita ou explicita) = - pode ser especificada em um bulk HQL query. Sub-queries podem= ser usadas na clausula = - where; as subqueries podem conter joins. - - - - - A clausula where tamb=C3=A9m =C3=A9 opcional. - - - - - - Como exemplo para executar um HQL UPDATE, u= se o = - m=C3=A9todo Query.executeUpdate()(o m=C3=A9= todo ganhou o nome = - devido a sua familiaridade com o do JDBC = - PreparedStatement.executeUpdate()): - - - - - - HQL UPDATE statements, by default do not ef= fect the - version - or the timesta= mp property values - for the affected entities; this is in keeping with the EJB3 sp= ecification. However, - you can force Hibernate to properly reset the version= or - timestamp property values through the use o= f a versioned update. - This is achieved by adding the VERSIONED ke= yword after the UPDATE - keyword. - = - - - - - Note that custom version types (org.hibernate.usertyp= e.UserVersionType) - are not allowed in conjunction with a update versione= d statement. - - - - - Para executar um HQL DELETE, use o mesmo m= =C3=A9todo = - Query.executeUpdate(): - - - - - - O valor int retornado pelo m=C3=A9todo Query.executeUpdate() - indica o numero de entidade afetadas pela opera=C3=A7=C3=A3o. = Lembre-se que isso pode estar ou n=C3=A3o = - relacionado ao n=C3=BAmero de linhas alteradas no banco de dad= os. Uma opera=C3=A7=C3=A3o bulk HQL pode resultar = - em v=C3=A1rias express=C3=B5es SQL reais a serem executadas, p= or exemplo, no caso de joined-subclass. = - O n=C3=BAmero retornado indica a quantidade real de entidades = afetadas pela express=C3=A3o. Voltando = - ao exemplo da joined-subclass, a exclus=C3=A3o de uma das subc= lasses pode resultar numa = - exclus=C3=A3o em outra tabelas, n=C3=A3o apenas na tabela para= qual a subclasses est=C3=A1 mapeada, mas = - tamb=C3=A9m tabela "root" e possivelmente nas tabelas joined-s= ubclass num n=C3=ADvel hier=C3=A1rquico = - imediatamente abaixo. - - - - = - A pseudo-sintaxe para o comando INSERT =C3= =A9: = - INSERT INTO EntityName properties_list select_stateme= nt. Alguns = - pontos a observar: - - - - - - Apenas a forma INSERT INTO ... SELECT ... =C3=A9 supor= tada; INSERT INTO ... VALUES ... = - n=C3=A3o =C3=A9 suportada. - - - A lista de propriedade =C3=A9 an=C3=A1loga =C3=A0 especifica=C3=A7=C3=A3o da coluna = - do comando SQL INSERT. Para entidad= es envolvidas em mapeamentos, = - apenas a propriedades definidas diretamente a n=C3=ADv= el da classe podem ser usandas na = - properties_list. Propriedades da superclass n=C3=A3o s= =C3=A3o permitidas; e as propriedades = - da subclasse n=C3=A3o faz sentido. Em outras palavras,= os comandos = - INSERT n=C3=A3o s=C3=A3o polimorfic= os. - - - - - O camando select pode ser qualquer query HQL v=C3=A1li= da, que tenha um retorno compat=C3=ADvel = - com o tipo com o esperado pela inclus=C3=A3o. Atualmen= te, isto =C3=A9 verificado durante a compila=C3=A7=C3=A3o = - da query, isto =C3=A9 melhor do que permitir que a ver= ifica=C3=A7=C3=A3o chegue ao banco de dados. = - Entretanto perceba que isso pode causar problemas entr= e os Tipo do Hibernate = - que s=C3=A3o equivalentes em opos= i=C3=A7=C3=A3o a equal. = - Isso pode causar problemas nas combina=C3=A7=C3=B5es e= ntre a propriedade definida como = - org.hibernate.type.DateTypee um pro= priedade definida como = - org.hibernate.type.TimestampType, e= mbora o banco de dados n=C3=A3o possa = - fazer uma distin=C3=A7=C3=A3o ou possa ser capaz de ma= nusear a convers=C3=A3o. - - - - - Para a propriedade id, a express=C3=A3o insert oferece= duas op=C3=A7=C3=B5es. Voc=C3=AA pode especificar = - qualquer propriedade id explicitamente no properties_l= ist (em alguns casos esse valor = - =C3=A9 obtido diretamente da express=C3=A3o select) ou= pode omitir do properties_list (nesse caso, = - um valor gerado =C3=A9 usado). Essa ultima op=C3=A7=C3= =A3o s=C3=B3 =C3=A9 v=C3=A1lida quando s=C3=A3o usados geradores de ids = - que operam no banco de dados; a tentativa de usar essa= op=C3=A7=C3=A3o com geradores do tipo = - "em mem=C3=B3ria" vai causar um exce=C3=A7=C3=A3o dura= nte a etapa de parser. Veja a finalidades desta = - discuss=C3=A3o, os seguintes geradores operam com o ba= nco de dados = - org.hibernate.id.SequenceGenerator = (e suas subclasses) = - e qualquer implementa=C3=A7=C3=A3o de org.hib= ernate.id.PostInsertIdentifierGenerator. = - Aqui, a exce=C3=A7=C3=A3o mais not=C3=A1vel =C3=A9 o <= literal>org.hibernate.id.TableHiLoGenerator, que = - n=C3=A3o pode ser usado porque ele n=C3=A3o disp=C3=B5= e de mecanismos para recuperar o seu valor. - - - - - For properties mapped as either version or timestamp, - the insert statement gives you two options. You can e= ither 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= seed value defined - by the org.hibernate.type.VersionType is used). - = - Para propriedades mapeadas como version ou timestamp, = - a express=C3=A3o insert oferece a voc=C3=AA duas op=C3= =A7=C3=B5es. Voc=C3=AA pode especificar a propriedade na = - properties_list (nesse caso o seu valor =C3=A9 obtido = a partir da express=C3=A3o select correspondente) = - ou ele pode ser omitido da properties_list (neste caso= o usa o valor semente - definido pela classe org.hibernate.type.Versi= onType). - - - - - - Exemplo da execu=C3=A7=C3=A3o de um HQL INSERT: - - - - - - - + + Processamento de lotes + = + + Uma alternativa para inserir 100.000 linhas no banco de dados usan= do o Hibernate = + pode ser a seguinte: = + + + + + + Isto ir=C3=A1 falhar em algum lugar pr=C3=B3ximo a linha 50.000, l= an=C3=A7ando uma = + OutOfMemoryException. Isso ocorre devido ao fat= o do Hibernate = + fazer cache de todas as inst=C3=A2ncias de Customer inseridas num = + cach=C3=AA em n=C3=ADvel de sess=C3=A3o. + + + + Neste cap=C3=ADtulo veremos como contornar esse problema. Entreta= nto, se voc=C3=AA vai realizar = + processamento de lotes, =C3=A9 muito importante que voc=C3=AA habi= lite o uso de lotes JDBC, se = + voc=C3=AA pretende obter um desempenho razo=C3=A1vel. Defina o tam= anho do lote JDBC em um = + valor razo=C3=A1vel (algo entre 10-50): + + = + + + + Voc=C3=AA tamb=C3=A9m pode querer rodar esse tipo de processamento= de lotes com o cache = + secund=C3=A1rio completamente desabilitado: + + + + + Note that Hibernate disables insert batching at the JDBC level transparen= tly if you + use an identiy identifier generator. + + + + Mas isto n=C3=A3o =C3=A9 absolutamente necess=C3=A1rio, desde que = n=C3=B3s possamos ajustar o = + CacheMode para desabilitar a intera=C3=A7=C3= =A3o com o cache secund=C3=A1rio. + + + + Inser=C3=A7=C3=A3o de lotes + + + Quando voc=C3=AA estiver inserindo novos objetos persistentes,= voc=C3=AAs deve executar = + os m=C3=A9todos flush() e clear()= regularmente + na sess=C3=A3o, para controlar o tamanho do cache prim=C3=A1ri= o. = + + + + + + + + Batch updates + + + Para recuperar e atualizar informa=C3=A7=C3=B5es a mesma id=C3= =A9ia =C3=A9 v=C3=A1lida. Adicionalmente, = + pode precisar usar o scroll() para usar re= cursos no lado = + do servidor em queries que retornam muita informa=C3=A7=C3=A3o= . = + + + + + + = + + A interface StatelessSession + + Alternativamente, o Hibernate prov=C3=AA uma API orientada =C3= =A0 comandos, usada para = + transmitir um fluxo de dados de e para o banco de dados na for= ma de objetos soltos. = + Uma StatelessSession n=C3=A3o tem um conte= xto persistente associado e = + n=C3=A3o fornece muito das sem=C3=A2nticas de alto n=C3=ADvel = para controle do ciclo de vida. = + Em especial, uma StatelessSession n=C3=A3o implemente o cache = prim=C3=A1rio e nem interage = + com o cache secund=C3=A1rio ou query cache. Ele n=C3=A3o imple= menta salvamento transacional = + automatico ou checagem autom=C3=A1tica de mudan=C3=A7as. Opera= =C3=A7=C3=A3o realizadas usando uma = + StatelessSession n=C3=A3o fazem nenhum tipo de cascade com as = instancias associadas. = + As cole=C3=A7=C3=B5es s=C3=A3o ignoradas por uma StatelessSess= ion. Opera=C3=A7=C3=B5es realizadas com um = + StatelessSession ignoram a arquitetura de eventos e os interce= ptadores. = + StatelessSession s=C3=A3o vulner=C3=A1veis aos efeitos do alia= sing dos dados, devido a = + falta do cache prim=C3=A1rio. Uma StatelessSession =C3=A9 uma = abstra=C3=A7=C3=A3o de baixo n=C3=ADvel, = + muito mais pr=C3=B3xima do JDBC. = + + = + + + + Veja neste exempo, as instancias de Customer retornadas pela query = + s=C3=A3o imediatamente desvinculadas. Elas nunca ser=C3=A3o as= sossiadas =C3=A0 um contexto persistente. + + = + + As opera=C3=A7=C3=B5es insert(), update() e= delete() + definidos pela interface StatelessSession s= =C3=A3o considerados = + opera=C3=A7=C3=B5es diretas no banco de dados (row-level opera= tions), isso resulta em uma = + execu=C3=A7=C3=A3o imediata de comandos SQL INSERT, = UPDATE ou + DELETE respectivamente. Devido a isso, eles= possuem uma = + sem=C3=A2ntica bem diferente das opera=C3=A7=C3=B5es = save(), saveOrUpdate() = + ou delete() definidas na interface Session. + + + + + + Opera=C3=A7=C3=B5es no estilo DML + + + Como j=C3=A1 discutido, mapeamento objeto/relacional autom=C3= =A1tico e transparente =C3=A9 conseguido = + com a ger=C3=AAncia do estado do objeto. Com isto o estado daq= uele objeto fica dispon=C3=ADvel na = + mem=C3=B3ria, manipulando(usando as express=C3=B5es SQL Data Manipulation Language = + (SQL-style DML): INSERT, UPDATE, DELETE) = + os dados diretamente no banco de dados n=C3=A3o ir=C3=A1 afeta= r o estado registrado em mem=C3=B3ria. = + Entretanto, o Hibernate prov=C3=AA m=C3=A9todos para executar = queries SQL-style DML, que s=C3=A3o = + totalmente executas com HQL (Hibernate Query Language) = + (HQL). + + + + A pseudo-sintaxe para express=C3=B5es UPDATE e DELETE =C3=A9: = + ( UPDATE | DELETE ) FROM? NomeEntidade (WHERE condi= =C3=A7=C3=B5es_where)?. = + Algumas observa=C3=A7=C3=B5es: + + + + + + Na clausula from, a palavra chave FROM =C3=A9 opcional; + + + + + Somente uma entidade pode ser chamada na clausula from= ; opcionalmente pode ter + um alias. Se o nome da entidade for possuir um alias, = ent=C3=A3o qualquer propriedade = + referenciada deve usar esse alias qualificado; se o no= me da entidade n=C3=A3o possuir + um alias, ent=C3=A3o nenhuma das propriedade precisa u= sar o acesso qualificado. + + + + + Na joins (amba= s impl=C3=ADcita ou explicita) = + pode ser especificada em um bulk HQL query. Sub-queries podem= ser usadas na clausula = + where; as subqueries podem conter joins. + + + + + A clausula where tamb=C3=A9m =C3=A9 opcional. + + + + + + Como exemplo para executar um HQL UPDATE, u= se o = + m=C3=A9todo Query.executeUpdate()(o m=C3=A9= todo ganhou o nome = + devido a sua familiaridade com o do JDBC = + PreparedStatement.executeUpdate()): + + + + + + HQL UPDATE statements, by default do not ef= fect the + version + or the timesta= mp property values + for the affected entities; this is in keeping with the EJB3 sp= ecification. However, + you can force Hibernate to properly reset the version= or + timestamp property values through the use o= f a versioned update. + This is achieved by adding the VERSIONED ke= yword after the UPDATE + keyword. + = + + + + + Note that custom version types (org.hibernate.usertyp= e.UserVersionType) + are not allowed in conjunction with a update versione= d statement. + + + + + Para executar um HQL DELETE, use o mesmo m= =C3=A9todo = + Query.executeUpdate(): + + + + + + O valor int retornado pelo m=C3=A9todo Query.executeUpdate() + indica o numero de entidade afetadas pela opera=C3=A7=C3=A3o. = Lembre-se que isso pode estar ou n=C3=A3o = + relacionado ao n=C3=BAmero de linhas alteradas no banco de dad= os. Uma opera=C3=A7=C3=A3o bulk HQL pode resultar = + em v=C3=A1rias express=C3=B5es SQL reais a serem executadas, p= or exemplo, no caso de joined-subclass. = + O n=C3=BAmero retornado indica a quantidade real de entidades = afetadas pela express=C3=A3o. Voltando = + ao exemplo da joined-subclass, a exclus=C3=A3o de uma das subc= lasses pode resultar numa = + exclus=C3=A3o em outra tabelas, n=C3=A3o apenas na tabela para= qual a subclasses est=C3=A1 mapeada, mas = + tamb=C3=A9m tabela "root" e possivelmente nas tabelas joined-s= ubclass num n=C3=ADvel hier=C3=A1rquico = + imediatamente abaixo. + + + + = + A pseudo-sintaxe para o comando INSERT =C3= =A9: = + INSERT INTO EntityName properties_list select_stateme= nt. Alguns = + pontos a observar: + + + + + + Apenas a forma INSERT INTO ... SELECT ... =C3=A9 supor= tada; INSERT INTO ... VALUES ... = + n=C3=A3o =C3=A9 suportada. + + + A lista de propriedade =C3=A9 an=C3=A1loga =C3=A0 especifica=C3=A7=C3=A3o da coluna = + do comando SQL INSERT. Para entidad= es envolvidas em mapeamentos, = + apenas a propriedades definidas diretamente a n=C3=ADv= el da classe podem ser usandas na = + properties_list. Propriedades da superclass n=C3=A3o s= =C3=A3o permitidas; e as propriedades = + da subclasse n=C3=A3o faz sentido. Em outras palavras,= os comandos = + INSERT n=C3=A3o s=C3=A3o polimorfic= os. + + + + + O camando select pode ser qualquer query HQL v=C3=A1li= da, que tenha um retorno compat=C3=ADvel = + com o tipo com o esperado pela inclus=C3=A3o. Atualmen= te, isto =C3=A9 verificado durante a compila=C3=A7=C3=A3o = + da query, isto =C3=A9 melhor do que permitir que a ver= ifica=C3=A7=C3=A3o chegue ao banco de dados. = + Entretanto perceba que isso pode causar problemas entr= e os Tipo do Hibernate = + que s=C3=A3o equivalentes em opos= i=C3=A7=C3=A3o a equal. = + Isso pode causar problemas nas combina=C3=A7=C3=B5es e= ntre a propriedade definida como = + org.hibernate.type.DateTypee um pro= priedade definida como = + org.hibernate.type.TimestampType, e= mbora o banco de dados n=C3=A3o possa = + fazer uma distin=C3=A7=C3=A3o ou possa ser capaz de ma= nusear a convers=C3=A3o. + + + + + Para a propriedade id, a express=C3=A3o insert oferece= duas op=C3=A7=C3=B5es. Voc=C3=AA pode especificar = + qualquer propriedade id explicitamente no properties_l= ist (em alguns casos esse valor = + =C3=A9 obtido diretamente da express=C3=A3o select) ou= pode omitir do properties_list (nesse caso, = + um valor gerado =C3=A9 usado). Essa ultima op=C3=A7=C3= =A3o s=C3=B3 =C3=A9 v=C3=A1lida quando s=C3=A3o usados geradores de ids = + que operam no banco de dados; a tentativa de usar essa= op=C3=A7=C3=A3o com geradores do tipo = + "em mem=C3=B3ria" vai causar um exce=C3=A7=C3=A3o dura= nte a etapa de parser. Veja a finalidades desta = + discuss=C3=A3o, os seguintes geradores operam com o ba= nco de dados = + org.hibernate.id.SequenceGenerator = (e suas subclasses) = + e qualquer implementa=C3=A7=C3=A3o de org.hib= ernate.id.PostInsertIdentifierGenerator. = + Aqui, a exce=C3=A7=C3=A3o mais not=C3=A1vel =C3=A9 o <= literal>org.hibernate.id.TableHiLoGenerator, que = + n=C3=A3o pode ser usado porque ele n=C3=A3o disp=C3=B5= e de mecanismos para recuperar o seu valor. + + + + + For properties mapped as either version or timestamp, + the insert statement gives you two options. You can e= ither 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= seed value defined + by the org.hibernate.type.VersionType is used). + = + Para propriedades mapeadas como version ou timestamp, = + a express=C3=A3o insert oferece a voc=C3=AA duas op=C3= =A7=C3=B5es. Voc=C3=AA pode especificar a propriedade na = + properties_list (nesse caso o seu valor =C3=A9 obtido = a partir da express=C3=A3o select correspondente) = + ou ele pode ser omitido da properties_list (neste caso= o usa o valor semente + definido pela classe org.hibernate.type.Versi= onType). + + + + + + Exemplo da execu=C3=A7=C3=A3o de um HQL INSERT: + + + + + + + Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/be= st_practices.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_pra= ctices.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/best_pra= ctices.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Boas pr=C3=A1ticas = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/co= llection_mapping.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collecti= on_mapping.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/collecti= on_mapping.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Mapeamento de Cole=C3=A7=C3=B5es = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/co= mponent_mapping.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/componen= t_mapping.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/componen= t_mapping.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Mapeamento de Componentes = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/co= nfiguration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configur= ation.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/configur= ation.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,1792 +1,1789 @@ = -=EF=BB=BF=EF=BB=BF - - Configura=C3=A7=C3=A3o - = - - Devido ao fato de o Hibernate ser projetado para operar em v=C3=A1= rios ambientes diferentes, = - h=C3=A1 um grande n=C3=BAmero de par=C3=A2metros de configura=C3= =A7=C3=A3o. Felizmente, a maioria tem valores default = - l=C3=B3gicos e o Hibernate =C3=A9 distribu=C3=ADdo com um arquivo = hibernate.properties = - de exemplo no etc/ que mostra v=C3=A1rias op=C3= =A7=C3=B5es. Apenas coloque o arquivo = - de exemplo no seu classpath e personalize-o. - - - - 1.11 Configura=C3=A7=C3=A3o program=C3=A1tica - - - Uma inst=C3=A2ncia de org.hibernate.cfg.Configuration= - representa um conjunto inteiro de mapeamentos de tipos Java da= aplica=C3=A7=C3=A3o para = - um banco de dados SQL. O Configuration =C3= =A9 usado para construir = - uma SessionFactory (imut=C3=A1vel). Os mape= amentos s=C3=A3o compilados = - a partir de arquivos de mapeamento XML. - - - - - Voc=C3=AA pode obter uma inst=C3=A2ncia Configuration= intanciando- - o diretamente e especificando documentos de mapeamento XML. Se= o arquivo = - de mapeamento est=C3=A3o no classpath, use use addRes= ource(): - - - - - - Uma alternativa (=C3=A0s vezes melhor) =C3=A9 especificar a cl= asse mapeada, = - e permitir que o Hibernate encontre o documento de mapeamento = para voc=C3=AA: = - - - - - - Ent=C3=A3o o Hibernate procurar=C3=A1 pelos arquivos de mapeam= ento chamados = - /org/hibernate/auction/Item.hbm.xml e - /org/hibernate/auction/Bid.hbm.xml no class= path. - Esta abordagem elimina qualquer nome de arquivo de dif=C3=ADci= l compreens=C3=A3o. - - = - - Uma Configuration tamb=C3=A9m permite voc= =C3=AA especificar = - propriedades de configura=C3=A7=C3=A3o: - - - - = - - Este n=C3=A3o =C3=A9 o =C3=BAnico caminho para passar as propr= iedades de configura=C3=A7=C3=A3o = - para o Hibernate. As v=C3=A1rias op=C3=A7=C3=B5es incluem: - - - - - - Passar uma inst=C3=A2ncia de java.util.Proper= ties = - para Configuration.setProperties(). - - - - - Colocar hibernate.properties no dir= et=C3=B3rio = - raiz do classpath. - - - - - Determinar as propriedades do System = - usando java -Dproperty=3Dvalue. - - - - - Include <property> elements in - hibernate.cfg.xml (discussed later). - Incluir elementos <property> = no = - hibernate.cfg.xml (discutido mais t= arde). - - - - - - hibernate.properties =C3=A9 o caminho mais= facil = - se voc=C3=AA quer come=C3=A7ar mais r=C3=A1pido. - - - - O Configuration =C3=A9 entendido como um ob= jeto startup-time, = - =C3=A9 descartado uma vez que a SessionFactory =C3=A9 criada. - - - - = - - Obtendo uma SessionFactory - - - Quando todos os mapeamentos t=C3=AAm sido analisados pelo Configuration, = - a aplica=C3=A7=C3=A3o deve obter uma factory para as inst=C3= =A2ncias da Session. = - O objetivo desta factory =C3=A9 ser compartilhado por todas as= threads da aplica=C3=A7=C3=A3o: - - - - - - Hibernate permite sua aplica=C3=A7=C3=A3o instanciar mais do q= ue uma = - SessionFactory. Isto =C3=A9 =C3=BAtil se vo= c=C3=AA est=C3=A1 usando mais = - do que um banco de dados. - - - - - - Conex=C3=B5es JDBC - - - Normalmente, voc=C3=AA quer mandar criar a SessionFa= ctory criar um - pool de conex=C3=B5es JDBC para voc=C3=AA. Se voc=C3=AA seguir= essa abordagem, a abertura de uma = - Session =C3=A9 t=C3=A3o simples quanto: - - - - - = - - Assim que voc=C3=AA fizer algo que requer o acesso ao banco de= dados, uma = - conex=C3=A3o JDBC ser=C3=A1 obtida do pool. - - - - Para esse trabalho, n=C3=B3s necessitamos passar algumas propr= iedades da conex=C3=A3o JDBC = - para o Hibernate. Todos os nomes de propriedades Hibernate e s= em=C3=A2nticas s=C3=A3o definidas = - org.hibernate.cfg.Environment. N=C3=B3s ire= mos descrever agora = - o mais importantes configura=C3=A7=C3=B5es de conex=C3=A3o JDB= C. - - - - O Hibernate obter=C3=A1 conex=C3=B5es( e pool) usando java.sql.DriverManager - se voc=C3=AA determinar as seguintes propriedades: - - - - Propriedades JDBC Hibernate - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.connection.driver_class - - - Classe driver jdbc - - - - - hibernate.connection.url - - - URL jdbc - - - - - hibernate.connection.username - - - Usu=C3=A1rio do banco de dados - - - - - hibernate.connection.password - - - Senha do usu=C3=A1rio do banco de dados - - - - - hibernate.connection.pool_size - - - N=C3=BAmero m=C3=A1ximo de connecx=C3=B5es n= o pool - - - - -
- - - O algoritmo de pool de conex=C3=B5es do pr=C3=B3prio Hibernate= entretanto =C3=A9 completamente = - rudimentar. A inten=C3=A7=C3=A3o dele e ajudar a iniciar e n=C3=A3o para usar em um = - sistema de produ=C3=A7=C3=A3o ou at=C3=A9 para test= ar desempenho. Voc=C3=AA deveria usar = - uma ferramente de pool de terceiros para conseguir melhor dese= mpenho e estabilidade. = - Apenas especifique a propriedade hibernate.connection= .pool_size = - com a defini=C3=A7=C3=A3o do pool de conex=C3=B5es. Isto ir=C3= =A1 desligar o pool interno do Hibernate. = - Por exemplo, voc=C3=AA pode gostar de usar C3P0. - - - - O C3P0 =C3=A9 um pool conex=C3=A3o JDBC de c=C3=B3digo aberto = distribu=C3=ADdo junto com = - Hibernate no diret=C3=B3rio lib. O Hi= bernate usar=C3=A1 o = - C3P0ConnectionProvider para o pool de conex= =C3=A3o se = - voc=C3=AA configurar a propriedade hibernate.c3p0.*. Se voc=C3=AA = - gostar de usar Proxool consulte ao pacote hibernate.p= roperties = - e o web site do Hibernate para mais informa=C3=A7=C3=B5es. - - - - Aqui =C3=A9 um exemplo de arquivo hibernate.propertie= s para C3P0: - - - - - - Para usar dentro de um servidor de aplica=C3=A7=C3=A3o, voc=C3= =AA deve configurar = - o Hibernate para obter conex=C3=B5es de um application server = - Datasource registrado no JNDI. Voc=C3=AA ne= cessitar=C3=A1 = - determinar pelo menos uma das seguintes propriedades: - - - - Propriedades do Datasource do Hibernate - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.connection.datasource - - - Nome datasource JNDI - - - - - hibernate.jndi.url - - - URL do fornecedor JNDI (opcional) - - - - - hibernate.jndi.class - - - Classe do JNDI InitialContextFactor= y (opcional) - - - - - hibernate.connection.username - - - Usu=C3=A1rio do banco de dados (o= pcional) - - - - - hibernate.connection.password - - - Senha do usu=C3=A1rio do banco de dados (opcional) - - - - -
- - - Eis um exemplo de arquivo hibernate.properties para = - um servidor de aplica=C3=A7=C3=A3o fornecedor de datasources J= NDI: - - - - - - Conex=C3=B5es JDBC obtidas de um datasource JNDI ir=C3=A3o aut= omaticamente ir=C3=A3o participar = - das transa=C3=A7=C3=B5es gerenciadas pelo container no servido= r de aplica=C3=A7=C3=A3o. - - - - Arbitrariamente as propriedades de conex=C3=A3o podem ser acre= scentandas ao = - "hibernate.connnection" ao nome da propried= ade. Por exemplo, = - voc=C3=AA deve especificar o charSet usando= hibernate.connection.charSet.t. - - - - Voc=C3=AA pode definir sua pr=C3=B3pria estrat=C3=A9gia de plu= gin para obter conex=C3=B5es JDBC implementando = - a interface org.hibernate.connection.ConnectionProvid= er. Voc=C3=AA pode = - escolher uma implementa=C3=A7=C3=A3o customizada setando hibernate.connection.provider_class. - - -
- - - Propriedades opcionais de configura=C3=A7=C3=A3o - = - - H=C3=A1 um grande n=C3=BAmero de outras propriedades que contr= olam o comportamento do Hibernate = - em tempo de execu=C3=A7=C3=A3o. Todos s=C3=A3o opcionais e tem= valores default l=C3=B3gicos. - - - - Aviso: algumas destas propriedades s=C3=A3o somente = a "n=C3=ADvel de sistema". - Propriedades n=C3=ADvel de sistema podem ser determinados some= nte via java -Dproperty=3Dvalue - ou hibernate.properties. Elas n= =C3=A3opodem ser = - configuradas por outras t=C3=A9cnicas descritas abaixo. - - - - Hibernate Configuration Properties - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.dialect - - - O nome da classe de um Dialeto = - que permite o Hibernate gerar SQL otimizado pa= ra um banco de = - dados relacional em particular. - - Ex. = - full.classname.of.Dialect - - - - - - hibernate.show_sql - - - Escreve todas as instru=C3=A7=C3=B5es SQL no c= onsole. Esta =C3=A9 uma alternativa = - a configurar a categoria de log org.h= ibernate.SQL - para debug. - - Ex. = - true | false - - - - - - hibernate.format_sql - - - Imprime o SQL formatado no log e console. - - Ex. = - true | false - - - - - - hibernate.default_schema - - - Qualifica no sql gerado, os nome das tabelas s= em qualificar = - com schena/tablespace dado - - Ex. = - SCHEMA_NAME - - - - - - hibernate.default_catalog - - - Qualifica no sql gerado, os nome das tabelas s= em qualificar = - com cat=C3=A1logo dado - - Ex. = - CATALOG_NAME - - - - - - hibernate.session_factory_name - - - O SessionFactory ir=C3=A1 a= utomaticamente = - se ligar a este nome no JNDI depois de ter sid= o criado. - - Ex. = - jndi/composite/name - - - - - - hibernate.max_fetch_depth - - - Estabelece a "profundidade" m=C3=A1xima para = =C3=A1rvore outer join fetch = - para associa=C3=A7=C3=B5es finais =C3=BAnicas(= one-to-one,many-to-one). = - Um 0 desativa por default a= busca outer join. - - eg. = - Valores recomendados entre0 e 3 - - - - - - hibernate.default_batch_fetch_size - - - Determina um tamanho default para busca de ass= ocia=C3=A7=C3=B5es em lotes do Hibernate = - - eg. = - Valores recomendados 4,= 8, = - 16 - - - - - - hibernate.default_entity_mode - - - Determina um modo default para representa=C3= =A7=C3=A3o de entidades = - para todas as sess=C3=B5es abertas desta SessionFactory - - dynamic-map, d= om4j, - pojo - - - - - - hibernate.order_updates - - - For=C3=A7a o Hibernate a ordenar os updates SQ= L pelo valor da chave = - prim=C3=A1ria dos itens a serem atualizados. I= sto resultar=C3=A1 em menos = - deadlocks nas transa=C3=A7=C3=B5es em sistemas= altamente concorrente. - - Ex. = - true | false - - - - - - hibernate.generate_statistics - - - If enabled, Hibernate will collect statistics = useful for - performance tuning. - Se habilitado, o Hibernate coletar=C3=A1 estat= =C3=ADsticas =C3=BAties = - para performance tuning dos bancos. - - Ex. - true | false - - - - - - hibernate.use_identifer_rollback - - - Se habilitado, propriedades identificadoras ge= radas = - ser=C3=A3o zeradas para os valores default qua= ndo os = - objetos forem apagados. - - Ex. - true | false - - - - - - hibernate.use_sql_comments - - - Se ligado, o Hibernate ir=C3=A1 gerar coment= =C3=A1rios dentro do SQL, = - para facilitar o debugging, o valor default = =C3=A9 false. - - eg. - true | false - - - - - -
- - - JDBC Hibernate e Propriedades de Conex=C3=A3o - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.jdbc.fetch_size - - - Um valor maior que zero determina o tamanho do= fetch = - do JDBC( chamadas Statement.setFetchS= ize()). - - - - - hibernate.jdbc.batch_size - - - Um valor maior que zero habilita uso de batch = updates JDBC2 pelo Hibernate. - - Ex. - valores recomentados entre 5 e 30 - - - - - - hibernate.jdbc.batch_versioned_data - - - Sete esta propriedade como true se seu driver JDBC retorna = - o n=C3=BAmero correto de linhas no ex= ecuteBatch() ( =C3=89 usualmente = - seguro tornar esta op=C3=A7=C3=A3o ligada). O = Hibernate ent=C3=A3o ir=C3=A1 usar betched DML = - para automaticamente versionar dados. false por default. - - Ex. - true | false - - - - - - hibernate.jdbc.factory_class - - - Escolher um Batcher customi= zado. Muitas = - aplica=C3=A7=C3=B5es n=C3=A3o ir=C3=A3o necess= itar desta propriedade de configura=C3=A7=C3=A3o - - Ex. - classname.of.BatcherFactory - - - - - - hibernate.jdbc.use_scrollable_results= et - - - Habilita o uso de JDBC2 scrollable resultsets = pelo Hibernate. - Essa propriedade somente =C3=A9 necessaria qua= ndo se usa Conexe=C3=A7=C3=B5es - JDBC providas pelo usu=C3=A1rio, caso contr=C3= =A1rio o Hibernate os os = - metadados da conex=C3=A3o. - - Ex. = - true | false - - - - - - hibernate.jdbc.use_streams_for_binary= - - - Use streams para escrever/ler tipos b= inary - ou serializable para/a o JD= BC( propriedade a n=C3=ADvel de sistema). - - Ex. - true | false - - - - - - hibernate.jdbc.use_get_generated_keys= - - - Possibilita o uso PreparedStatement.g= etGeneratedKeys() = - do JDBC3 para recuperar chaves geradas nativam= ente depois da inser=C3=A7=C3=A3p. = - Requer driver JDBC3+ e JRE1.4+, determine para= false se seu driver tem = - problemas com gerador de indentificadores Hibe= rnate. Por default, tente = - determinar o driver capaz de usar metadados da= conex=C3=A3o. - - Ex. - true|false - - - - - - hibernate.connection.provider_class - - - O nome da classe de um ConnectionProv= ider personalizado - o qual prover=C3=A1 conex=C3=B5es JDBC para o = Hibernate. - - Ex. = - classname.of.ConnectionProvider - - - - - - hibernate.connection.isolation - - - Determina o n=C3=ADvel de isolamento de uma transa= =C3=A7=C3=A3o JDBC. = - Verifique java.sql.Connection p= ara valores = - siginificativos mas note que a maior parte dos ban= cos de dados = - n=C3=A3o suportam todos os n=C3=ADveis de isolamen= to. - - Ex. = - 1, 2, 4, 8 - - - - - - hibernate.connection.autocommit - - - Habilita autocommit para conex=C3=B5es no pool= JDBC( n=C3=A3o recomendado). - - Ex. - true | false - - - - - - hibernate.connection.release_mode - - - Especifica quando o Hibernate deve liberar con= ex=C3=B5es JDBC. Por default, = - uma conex=C3=A3o JDBC =C3=A9 retida at=C3=A9 a= sess=C3=A3o est=C3=A1 explicitamente fechada = - ou desconectada. Para um datasource JTA do ser= vidor de aplica=C3=A7=C3=A3o, voc=C3=AA deve = - usar after_statement para f= or=C3=A7ar s libera=C3=A7=C3=A3o da conex=C3=B5es = - depois de todas as chamadas JDBC. Para uma con= ex=C3=A3o n=C3=A3o-JTA, freq=C3=BCentemente = - faz sentido liberar a conex=C3=A3o ao fim de c= ada transa=C3=A7=C3=A3o, usando - after_transaction. auto escolheremos - after_statement para as es= trat=C3=A9gias de transa=C3=A7=C3=A3oes JTA e CMT = - e after_transaction para as= estrat=C3=A9gias de transa=C3=A7=C3=A3o JDBC - - Ex. = - auto (default) | on_close | - after_transaction | after_statement - - - Note that this setting only affects Sessions returned from - SessionFactory.openSession. For Sessions - obtained through SessionFactory.g= etCurrentSession, the - CurrentSessionContext i= mplementation configured for use - controls the connection release mode for t= hose Sessions. - See - - - - - - hibernate.connection.<proper= tyName> - - - Passa a propriedade JDBC propertyName = - para DriverManager.getConnection(). - - - - - hibernate.jndi.<property= Name> - - - Passar a propriedade propertyName para = - o InitialContextFactory JND= I. - - - - -
- - - Propriedades de Cach=C3=AA do Hibernate - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.cache.provider_class - - - O nome da classe de um CacheProvider<= /literal> customizado. - - Ex. = - classname.of.CacheProvider - - - - - - hibernate.cache.use_minimal_puts - - - Otimizar opera=C3=A7=C3=A3o de cach=C3=AA de s= egundo n=C3=ADvel para minimizar escritas, = - ao custo de leituras mais frequantes. Esta con= figura=C3=A7=C3=A3o =C3=A9 mais =C3=BAtil = - para cach=C3=AAs clusterizados e, no Hibernate= 3, =C3=A9 habilitado por default = - para implementa=C3=A7=C3=B5es de cach=C3=AA cl= usterizar. - - Ex. = - true|false - - - - - - hibernate.cache.use_query_cache - - - Habilita a cache de consultas, Mesmo assim, co= nsultas individuais ainda tem que ser = - habilitadas para o cache. - - Ex. = - true|false - - - - - - hibernate.cache.use_second_level_cach= e - - - May be used to completely disable the second l= evel cache, which is enabled - by default for classes which specify a <cache> - mapping. - Pode ser usada para desabilitar completamente = ocache de segundo n=C3=ADvel, = - o qual est=C3=A1 habilitado por default para c= lasses que especificam = - um mapeamento <cache>. - - - Ex. = - true|false - - - - - - hibernate.cache.query_cache_factory - - - O nome de uma classe que implementa a interfac= e = - QueryCache personalizada, p= or = - default, um StandardQueryCache - criado automaticamente. - - Ex. - classname.of.QueryCache - - - - - - hibernate.cache.region_prefix - - - Um prefixo para usar nos nomes da =C3=A1rea es= pecial = - do cach=C3=AA de segundo n=C3=ADvel. - - Ex. = - prefix - - - - - - hibernate.cache.use_structured_entrie= s - - - Forces Hibernate to store data in the second-l= evel cache - in a more human-friendly format. - For=C3=A7a o Hibernate armazenar dados no cach= =C3=AA se segundo = - n=C3=ADvel em um formato mais legivel. - - Ex. - true|false - - - - - -
- - - Propriedades de Transa=C3=A7=C3=A3o do Hibernate - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.transaction.factory_class - - - O nome da clase de um a TransactionFa= ctory - para usar com API Transaction - ( por default JDBCTransactionFactory). - - Ex. = - classname.of.TransactionFactory - - - - - - jta.UserTransaction - - - Um nome JNDI usado pelo JTATransactio= nFactory = - para obter uma UserTransaction JTA a partir = - do servidor de aplica=C3=A7=C3=A3o. - - Ex. = - jndi/composite/name - - - - - - hibernate.transaction.manager_lookup_= class - - - O nome da classe de um TransactionMan= agerLookup - =E2=80=93 requerido quando caching a n=C3=ADve= l JVM esta habilitado ou quando = - estivermos usando um generator hilo em um ambi= ente JTA. - - Ex. = - classname.of.TransactionManagerLo= okup - - - - - - hibernate.transaction.flush_before_co= mpletion - - - Se habilitado, a sess=C3=A3o ser=C3=A1 automat= icamente limpa antes da fase de = - conclus=C3=A3o da transa=C3=A7=C3=A3o. =C3=89 = preferivel a ger=C3=AAncia interna e = - autom=C3=A1tica do contexto da sess=C3=A3o, ve= ja - - - Ex. = - true | false - - - - - - hibernate.transaction.auto_close_sess= ion - - - Se habilitado, a sess=C3=A3o ser=C3=A1 automat= icamente fechada ap=C3=B3s a fase de - conclus=C3=A3o da transa=C3=A7=C3=A3o. =C3=89= preferivel a ger=C3=AAncia interna e = - autom=C3=A1tica do contexto da sess=C3=A3o, ve= ja - - - Ex. = - true | false - - - - - -
- - - Propriedades Variadas - - - - - - Nome da Propriedade - Prop=C3=B3sito - - - - - - hibernate.current_session_context_cla= ss - - - Forne=C3=A7e uma estrat=C3=A9gia (personalizad= a) para extens=C3=A3o = - da Session "corrente". Veja = - para = - mais informa=C3=A7=C3=A3o sobre estrat=C3=A9g= ias internas. - - Ex. - jta | thread | - managed | cust= om.Class - - - - - - hibernate.query.factory_class - - - Escolha a implementa=C3=A7=C3=A3o de an=C3=A1l= ise HQL. - - eg. = - org.hibernate.hql.ast.ASTQueryTra= nslatorFactory or - org.hibernate.hql.classic.Classic= QueryTranslatorFactory - - - - - - hibernate.query.substitutions - - - Mapeamento a partir de s=C3=ADmbolos em consul= tas HQL para = - s=C3=ADmbolos SQL( s=C3=ADmbolos devem ser fun= =C3=A7=C3=B5es ou nome literais - , por exemplo). - - eg. = - hqlLiteral=3DSQL_LITERAL, hqlFunc= tion=3DSQLFUNC - - - - - - hibernate.hbm2ddl.auto - - - Automaticamente valida ou exporta schema DDL p= ara o banco de = - dados quando o SessionFactory =C3=A9 criads. - Com create-drop, o schema d= o banco de dados = - ser=C3=A1 excluido quando a create-dr= op for - fechada esplicitamente. - - Ex. = - validate | upd= ate | = - create | creat= e-drop - - - - - - hibernate.cglib.use_reflection_optimi= zer - - - Habilita o uso de CGLIB em vez de reflex=C3=A3= o em tempo de execu=C3=A7=C3=A3o - ( propriedade a n=C3=ADvel de sistema). Reflex= =C3=A3o pode algumas vezes ser =C3=BA - til quando controlar erros, note que o Hiberna= te sempre ir=C3=A1 requerer a CGLIB = - mesmo se voc=C3=AA desligar o otimizador. Voc= =C3=AA n=C3=A3o pode determinar esta = - propriedade no hibernate.cfg.xml. - - Ex. = - true | false - - - - - -
- - - Dialetos SQL - - - Voc=C3=AA deve sempre determinar a propriedade hi= bernate.dialect = - para a subclasse de org.hibernate.dialect.Dialect= correta de seu = - banco de dados. Se voc=C3=AA especificar um dialeto, Hiber= nate usar=C3=A1 defaults l=C3=B3gicos = - para qualquer um das outras propriedades listadas abaixo, = reduzindo o esfor=C3=A7o de = - especific=C3=A1-los manualmente. = - - - - Hibernate SQL Dialects (<literal>hibernate.dialect<= /literal>) - - - - - - RDBMS - Dialect - - - - - DB2 org.hiberna= te.dialect.DB2Dialect - - - DB2 AS/400 org.= hibernate.dialect.DB2400Dialect - - - DB2 OS390 org.h= ibernate.dialect.DB2390Dialect - - - PostgreSQL org.= hibernate.dialect.PostgreSQLDialect - - - MySQL org.hiber= nate.dialect.MySQLDialect - - - MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect - - - MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect - - - Oracle (any version) org.hibernate.dialect.OracleDialect - - - Oracle 9i/10g o= rg.hibernate.dialect.Oracle9Dialect - - - Sybase org.hibe= rnate.dialect.SybaseDialect - - - Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect - - - Microsoft SQL Server org.hibernate.dialect.SQLServerDialect - - - SAP DB org.hibe= rnate.dialect.SAPDBDialect - - - Informix org.hi= bernate.dialect.InformixDialect - - - HypersonicSQL o= rg.hibernate.dialect.HSQLDialect - - - Ingres org.hibe= rnate.dialect.IngresDialect - - - Progress org.hi= bernate.dialect.ProgressDialect - - - Mckoi SQL org.h= ibernate.dialect.MckoiDialect - - - Interbase org.h= ibernate.dialect.InterbaseDialect - - - Pointbase org.h= ibernate.dialect.PointbaseDialect - - - FrontBase org.h= ibernate.dialect.FrontbaseDialect - - - Firebird org.hi= bernate.dialect.FirebirdDialect - - - -
- -
- - - Recupera=C3=A7=C3=A3o por uni=C3=A3o externa (Outer Joi= n Fetching) - - - Se seu banco de dados suporta Recupera=C3=A7=C3=A3o por un= i=C3=A3o externa (Outer Join Fetching) no estilo ANSI, = - Oracle ou Sybase, A recupera=C3=A7=C3=A3o por uni=C3=A3o e= xterna (Outer Join Fetching) frequentemente aumentar=C3=A1 - o desempenho limitando o n=C3=BAmero de chamadas (round tr= ips) ao banco de dados( ao custo de = - possivelmente mais trabalho desempenhado pelo pr=C3=B3prio= banco de dados). A recupera=C3=A7=C3=A3o por = - uni=C3=A3o externa (Outer Join Fetching)permite um gr=C3= =A1fico completo de objetos conectados = - por muitos-para-um, um-para-muitos, muitos-para-muitos e a= ssocia=C3=A7=C3=B5es um-para-um para ser = - recuperadas em um simples instru=C3=A7=C3=A3o SQL SELECT . - - - - - A recupera=C3=A7=C3=A3o por uni=C3=A3o externa (Outer Join= Fetching) pode ser desabilitado = - globalmente setando a propriedade = - hibernate.max_fetch_depth para 0. = - Uma valor 1 ou maior habilita o outer join fetching para a= ssocia=C3=A7=C3=B5es um-para-um = - e muitos-para-umos cujos quais tem sido mapeado com fetch=3D"join". - - - - Veja para mais in= forma=C3=A7=C3=B5es. - - - - - - Fluxos Bin=C3=A1rios (Binary Streams) - - - O Oracle limita o tamanho de arrays de byte que pode ser = - passado para/de o driver JDBC. Se voc=C3=AA desejar usar g= randes inst=C3=A2ncias de = - tipos binary ou serializable<= /literal>, voc=C3=AA = - deve habilitar hibernate.jdbc.use_streams_for_bin= ary. - Essa =C3=A9 uma configura=C3=A7=C3=A3o que s=C3= =B3 pode ser feita a n=C3=ADvel de sistema. - - - - - - Cach=C3=AA de segundo n=C3=ADvel e query - - - As propriedades prefixadas pelo hibernate.cache = - permite voc=C3=AA usar um sistema de cach=C3=AA de segundo= n=C3=ADvel = - em um processo executado em clustercom Hibernate. = - Veja para mais detal= hes. - - - - - - Substitui=C3=A7=C3=B5es na Linguagem de Consulta - - - Voc=C3=AA pode definir novos s=C3=ADmbolos de consulta Hib= ernate usando = - hibernate.query.substitutions. = - Por exemplo: - - - hibernate.query.substitutions true=3D1, false= =3D0 - - - Faria com que os s=C3=ADmbolos true e <= literal>false = - passasem a ser traduzidos para literais inteiro no SQL ger= ado. - - - hibernate.query.substitutions toLowercase=3DLO= WER - - - permitir=C3=A1 voc=C3=AA renomear a fun=C3=A7=C3=A3o LOWER no SQL. - - - - - - Estat=C3=ADsticas do Hibernate - - - If you enable hibernate.generate_statistics, Hibernate will = - expose a number of metrics that are useful when tuning a r= unning system via - SessionFactory.getStatistics(). Hiberna= te can even be configured - to expose these statistics via JMX. Read the Javadoc of th= e interfaces in - org.hibernate.stats for more informatio= n. - = - Se voc=C3=AA habilitar hibernate.generate_statist= ics, o Hibernate = - exibir=C3=A1 um n=C3=BAmero de m=C3=A9tricas bastante =C3= =BAtil ao ajustar um sistema via - SessionFactory.getStatistics(). O Hiber= nate pode at=C3=A9 ser = - configurado para exibir essas estat=C3=ADsticas via JMX. L= eia o Javadoc da interface - org.hibernate.stats para mais informa= =C3=A7=C3=B5es. - - - -
- - - Logging - - - Hibernate registra v=C3=A1rios eventos usando Apache commons-l= ogging. - - - - O servi=C3=A7o commons-logging direcionar=C3=A1 a sa=C3=ADda p= ara o Apache Log4j - ( se voc=C3=AA incluir log4j.jarr no seu cl= asspath) ou = - JDK1.4 logging( se estiver em uso JDK1.4 ou maior). Voc=C3=AA = pode fazer o = - download do Log4j a partir de http://jakarta.apache.= org. - Para usar Log4j voc=C3=AA necessitar=C3=A1 colocar um arquivo = - log4j.properties no seu classpath, um exemp= lo de arquivo - de propriedades =C3=A9 distribu=C3=ADdo com o Hibernate no dir= et=C3=B3rio = - src/. - - - = - - We strongly recommend that you familiarize yourself with Hiber= nate's log - messages. A lot of work has been put into making the Hibernate= log as - detailed as possible, without making it unreadable. It is an e= ssential - troubleshooting device. The most interesting log categories ar= e the - following: - = - N=C3=B3s recomendamos enfaticamente que voc=C3=AA se familiari= ze-se com mensagens de = - log do Hibernate. Uma parte do trabalho tem sido posto em faze= r o log = - Hibernate t=C3=A3o detalhado quanto poss=C3=ADvel, sem faz=C3= =AA-lo ileg=C3=ADvel. = - =C3=89 um essencial dispositivos de controle de erros. As cate= gorias de log = - mais interessantes s=C3=A3o as seguintes: - - = - - Categorias de Log do Hibernate - - - - - - Categoria - Fun=C3=A7=C3=A3o - - - - - org.hibernate.SQL - Registra todas as instru=C3=A7=C3=B5es = SQL DML a medida que elas s=C3=A3o executadas - - - org.hibernate.type - Registra todos os par=C3=A2metros JDBC<= /entry> - - - org.hibernate.tool.hbm2ddl - Registra todas as instru=C3=A7=C3=B5es = SQL DDL a medida que elas s=C3=A3o executadas - - - org.hibernate.pretty= - - Log the state of all entities (max 20 enti= ties) associated - with the session at flush time - Registra o estado de todas as entidades (m= =C3=A1ximo 20 entidades) = - associadas a session no momento da limpeza= (flush). - - - - org.hibernate.cache<= /entry> - Registra todas as atividades de cach=C3= =AA de segundo n=C3=ADvel - - - org.hibernate.transaction - Registra atividades relacionada a trans= a=C3=A7=C3=A3o - - - org.hibernate.jdbc - Registra todas as requisi=C3=A7=C3=B5es= de recursos JDBC - - - org.hibernate.hql.ast.AST - - Registra instru=C3=A7=C3=B5es SQL e HQL du= rante a an=C3=A1lise da consultas - - - - org.hibernate.secure= - Registra todas as requisi=C3=A7=C3=B5es= de autoriza=C3=A7=C3=A3o JAAS - - - org.hibernate - - Registra tudo ( uma parte das informa=C3= =A7=C3=B5es, mas muito = - =C3=BAtil para controle de erros ) - - - - -
- = - - Quando desenvolver aplica=C3=A7=C3=B5es com Hibernate, voc=C3= =AA deve quase sempre trabalhar com = - debug debug para a categoria org.= hibernate.SQL, = - ou, alternativamente, a com a propriedade hibernate.s= how_sql habilitada. - - = - = -
- - - Implementado uma <literal>NamingStrategy</literal> - - - A interface org.hibernate.cfg.NamingStrategy permite voc=C3=AA = - especificar um "padr=C3=A3o de nomea=C3=A7=C3=A3o" para objeto= s do banco de dados e elementos schema. - - - - Voc=C3=AA deve criar regras para a gera=C3=A7=C3=A3o automatic= amente de identificadores = - do banco de dados a partir de identificadores Java ou para pro= cessar = - colunas "computadas" e nomes de tabelas dado o arquivo de mape= amento = - para nomes "f=C3=ADsicos" de tabelas e colunas. Esta caracter= =C3=ADstica ajuda a = - reduzir a verbosidade do documento de mapeamento, eliminando i= nterfer=C3=AAncias = - repetitivas( TBL_prefixos, por exemplo). A = estrat=C3=A9gia = - default usada pelo Hibernate =C3=A9 completamente m=C3=ADnima. - - - - Voc=C3=AA pode especificar uma estrat=C3=A9gia diferente ao ch= amar = - Configuration.setNamingStrategy() antes de = adicionar = - os mapeamentos: - - - - = - - org.hibernate.cfg.ImprovedNamingStrategy = =C3=A9 uma estrat=C3=A9gia = - interna que pode ser um ponto de come=C3=A7o =C3=BAtil para al= gumas aplica=C3=A7=C3=B5es. - - - - - - Arquivo de configura=C3=A7=C3=A3o XML - - - Uma maneira alternativa de configura=C3=A7=C3=A3o =C3=A9 espec= ificar uma configura=C3=A7=C3=A3o completa = - em um arquivo chamado hibernate.cfg.xml. Es= te arquivo pode = - ser usado como um substituto para o arquivo hibernate= .properties = - ou, se ambos est=C3=A3o presentes, sobrescrever propriedades. - - - - The XML configuration file is by default expected to be in the= root o - your CLASSPATH. Here is an example: - O arquivo XML de configura=C3=A7=C3=A3o =C3=A9 por default esp= erado para estar na = - raiz do seu CLASSPATH. Veja um exemplo: - - - - - - - - - - - - java:/comp/env/jdbc/MyDB<= /property> - org.hibernate.dialect.MySQLDialect - false - - org.hibernate.transaction.JTATransactionFactory - - java:comp/UserTransaction - - - - - - - - - - - - -]]> - - - Como voc=C3=AA pode ver, a vantagem deste enfoque =C3=A9 a ext= ernaliza=C3=A7=C3=A3o dos nomes dos = - arquivos de mapeamento para configura=C3=A7=C3=A3o. O hibernate.cfg.xml = - tamb=C3=A9m =C3=A9 mais conveniente caso voc=C3=AA tenha que a= justar o cache do Hibernate. = - Note que a escolha =C3=A9 sua em usar hibernate.pro= perties ou - hibernate.cfg.xml, ambos s=C3=A3o equivalen= te, =C3=A0 exce=C3=A7=C3=A3o dos benef=C3=ADcios = - acima mencionados de usar a sintaxe de XML. - - - - Com a configura=C3=A7=C3=A3o do XML, iniciar o Hibernate =C3=A9= ent=C3=A3o t=C3=A3o simples como - - - - - - You can pick a different XML configuration file using - - - - - - - - Integra=C3=A7=C3=A3o com servidores de aplica=C3=A7=C3=A3o = J2EE - - - O Hibernate tem os seguintes pontos da integra=C3=A7=C3=A3o pa= ra o infraestrutura de J2EE: - - - - - - DataSources gerenciados pelo container: O Hibernate pode = - usar conex=C3=B5es JDBC gerenciadas pelo Container e forne= cidas pela JNDI. Geralmente, = - um TransactionManager compat=C3=ADvel c= om JTA e um = - ResourceManager cuidam do gerenciamento= da transa=C3=A7=C3=A3o ( CMT ), = - especialmente em transa=C3=A7=C3=B5es distribu=C3=ADdas ma= nipuladas atrav=C3=A9s de v=C3=A1rios DataSources. = - Naturalmente, voc=C3=AA tamb=C3=A9m pode demarcar os limit= es das transa=C3=A7=C3=B5es programaticamente (BMT) = - ou voc=C3=AA poderia querer usar a API opcional do Hiberna= te Transaction - para esta manter seu c=C3=B3digo port=C3=A1vel. - - - - - - - - Liga=C3=A7=C3=A3o (binding) autom=C3=A1tica a JN= DI: O Hibernate pode = - associar sua SessionFactory a JNDI depo= is de iniciado. - - - - - - - - Liga=C3=A7=C3=A3o (binding) Session na JTA: = - A Session do Hibernate pode automaticam= ente ser ligada = - ao escopo da transa=C3=A7=C3=B5es JTA. Simplesmente locali= zando a SessionFactory = - da JNDI e obtendo aSession corrente. De= ixe o Hibernate cuidar = - da limpeza e encerramento da Session qu= ando as transa=C3=A7=C3=B5es JTA = - terminarem. A Demarca=C3=A7=C3=A3o de transa=C3=A7=C3=A3o = pode ser declarativa (CMT) ou = - program=C3=A1tica(BMT/Transa=C3=A7=C3=A3o do usu=C3=A1rio). - - - - - - - - JMX deployment: Se voc=C3=AA usa um J= MX servidor de = - aplica=C3=A7=C3=B5es capaz (ex. Jboss AS), voc=C3=AA pode = fazer a insta=C3=A7=C3=A3o do Hibernate = - como um Mbean controlado. Isto evita ter que iniciar uma l= inha de = - c=C3=B3digo para construir sua SessionFactory de uma = - Configuration. O container iniciar=C3= =A1 seu = - HibernateService, e idealmente tamb=C3= =A9m cuidar=C3=A1 = - das depend=C3=AAncias de servi=C3=A7os (DataSources, t=C3= =AAm que estar dispon=C3=ADveis = - antes do Hibernate iniciar, etc.). - - - - - - Dependendo em seu ambiente, voc=C3=AA poderia ter que ajustar= a op=C3=A7=C3=A3o de configura=C3=A7=C3=A3o = - hibernate.connection.aggressive_release par= a verdadeiro ( true ), = - se seu servidor de aplica=C3=A7=C3=B5es lan=C3=A7ar exe=C3=A7= =C3=B5es "reten=C3=A7=C3=A3o de conec=C3=A7=C3=A3o". - - - - Configura=C3=A7=C3=A3o de estrat=C3=A9gia de transa=C3= =A7=C3=A3o - - - A API Hibernate Session =C3=A9 independ= ente de qualquer sistema de = - demarca=C3=A7=C3=A3o de transa=C3=A7=C3=A3o em sua arquite= tura. Se voc=C3=AA deixar o Hibernate usar = - a JDBC diretamente, atrav=C3=A9s de um pool de conex=C3=B5= es, voc=C3=AA pode inicializar e = - encerrar suas transa=C3=A7=C3=B5es chamando a API JDBC. S= e voc=C3=AA rodar em um servidor de = - aplica=C3=A7=C3=B5es J2EE, voc=C3=AA poder=C3=A1 usar tran= sa=C3=A7=C3=B5es controladas por beans e chamar = - a API JTA e UserTransaction quando nece= ss=C3=A1rio. - - - - - Para manter seu c=C3=B3digo port=C3=A1vel entre estes dois= ( e outros ) ambientes, recomendamos = - a API Hibernate Transaction, que envolv= e e esconde o sistema subjacente. = - Voc=C3=AA tem que especificar um classe construtora para <= literal>Transaction instanciar = - ajustando a propriedade de configura=C3=A7=C3=A3o do hibernate.transaction.factory_class. - - - - - Existem tr=C3=AAs escolhas (internas) padr=C3=B5es: - - - - - org.hibernate.transaction.JDBCTransacti= onFactory - - delegada as transa=C3=A7=C3=B5es (JDBC)a bas= es de dados (Padr=C3=A3o) - = - - - - org.hibernate.transaction.JTATransactio= nFactory - - - delegada a transa=C3=A7=C3=A3o a um container = gerenciador se a transa=C3=A7=C3=A3o = - existente estiver de acordo neste contexto (ex= : m=C3=A9todo bean sess=C3=A3o EJB), = - se n=C3=A3o uma nova transa=C3=A7=C3=A3o =C3= =A9 iniciada e uma transa=C3=A7=C3=A3o controlado por = - um bean =C3=A9 usada. - - - - - org.hibernate.transaction.CMTTransactio= nFactory - - delega para um container gerenciador de tran= sa=C3=A7=C3=B5es JTA - - - - - - Voc=C3=AA tamb=C3=A9m pode definir suas pr=C3=B3prias estr= at=C3=A9gias de transa=C3=A7=C3=A3o ( para um servi=C3=A7o de = - transa=C3=A7=C3=A3o CORBA por exemplo). - - - - Algumas caracter=C3=ADsticas no Hibernate (ex., o cache de= segundo n=C3=ADvel, sess=C3=B5es contextuais = - com JTA, etc.) requerem acesso a JTA TransactionM= anager em um ambiente = - controlado. Em um servidor de aplica=C3=A7=C3=A3o voc=C3= =AA tem que especificar como o Hibernate pode = - obter uma refer=C3=AAncia para a TransactionManag= er, pois o J2EE n=C3=A3o = - padronize um mecanismo simples : - - - - Gerenciadores de transa=C3=A7=C3=B5es JTA - - - - - - Transaction Factory - Application Server - - - - - org.hibernate.transaction.JBos= sTransactionManagerLookup - JBoss - - - org.hibernate.transaction.Webl= ogicTransactionManagerLookup - Weblogic - - - org.hibernate.transaction.WebS= phereTransactionManagerLookup - WebSphere - - - org.hibernate.transaction.WebS= phereExtendedJTATransactionLookup - WebSphere 6 - - - org.hibernate.transaction.Orio= nTransactionManagerLookup - Orion - - - org.hibernate.transaction.Resi= nTransactionManagerLookup - Resin - - - org.hibernate.transaction.JOTM= TransactionManagerLookup - JOTM - - - org.hibernate.transaction.JOnA= STransactionManagerLookup - JOnAS - - - org.hibernate.transaction.JRun= 4TransactionManagerLookup - JRun4 - - - org.hibernate.transaction.BEST= ransactionManagerLookup - Borland ES - - - -
- -
- - - <literal>SessionFactory</literal> ligada a JNDI - - - Uma SessionFactory de Hibernate ligada = a JNDI pode simplificar - a localiza=C3=A7=C3=A3o da fabrica e a cria=C3=A7=C3=A3o d= e novas Sessions. - Observe que isto n=C3=A3o relacionado a um Dataso= urce ligado = - a JNDI, simplemente ambos usam o mesmo registro! - - - - If you wish to have the SessionFactory = bound to a JNDI namespace, specify - a name (eg. java:hibernate/SessionFactory) using the property - hibernate.session_factory_name. If this= property is omitted, the - SessionFactory will not be bound to JND= I. (This is especially useful in - environments with a read-only JNDI default implementation,= e.g. Tomcat.) - - - - When binding the SessionFactory to JNDI= , Hibernate will use the values of - hibernate.jndi.url, hibernate.= jndi.class to instantiate - an initial context. If they are not specified, the default= InitialContext - will be used. - - - - Hibernate will automatically place the SessionFac= tory in JNDI after - you call cfg.buildSessionFactory(). Thi= s means you will at least have - this call in some startup code (or utility class) in your = application, unless you use - JMX deployment with the HibernateService (discussed later). - - - - If you use a JNDI SessionFactory, an EJ= B or any other class may - obtain the SessionFactory using a JNDI= lookup. - - - - We recommend that you bind the SessionFactory to JNDI in - a managend environment and use a static= singleton otherwise. - To shield your application code from these details, we als= o 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. - - - - - - Current Session context management with JTA - - - The easiest way to handle Sessions and = transactions is - Hibernates automatic "current" Session = management. - See the discussion of current sessions. - Using the "jta" session context, if the= re 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 Sessions - retrieved via getCurrentSession() in "jta" context - will be set to automatically flush before the transaction com= pletes, close - after the transaction completes, and aggressively release JDB= C connections - after each statement. This allows the Sessions 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 cod= e 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, decla= rative transaction - demarcation with CMT is preferred. - - - - - - JMX deployment - - - The line cfg.buildSessionFactory() stil= l has to be executed - somewhere to get a SessionFactory into = JNDI. You can do this - either in a static initializer block (l= ike the one in - HibernateUtil) or you deploy Hibernate = as a managed - service. - - - - Hibernate is distributed with org.hibernate.jmx.H= ibernateService - for deployment on an application server with JMX capabilit= ies, such as JBoss AS. - The actual deployment and configuration is vendor specific= . Here is an example - jboss-service.xml for JBoss 4.0.x: - - - - - - - - - jboss.jca:service=3DRARDeployer - jboss.jca:service=3DLocalTxCM,name=3DHsqlDS - - - java:/hibernate/SessionFactory - - - java:HsqlDS - org.hibernate.dialect.HSQLDialect - - - - org.hibernate.transaction.JTATransactionFactory - - org.hibernate.transaction.JBossTransactionManagerLookup - true - true - - - 5 - - - true - org.hibernate.cache.EhCacheProv= ider - true - - - true - - - auction/Item.hbm.xml,auction/Category= .hbm.xml - - - -]]> - - - This file is deployed in a directory called META-= INF and packaged - in a JAR file with the extension .sar (= service archive). You also need - to package Hibernate, its required third-party libraries, = your compiled persistent classes, - as well as your mapping files in the same archive. Your en= terprise beans (usually session - beans) may be kept in their own JAR file, but you may incl= ude this EJB JAR file in the - main service archive to get a single (hot-)deployable unit= . Consult the JBoss AS - documentation for more information about JMX service and E= JB deployment. - - - - -
- -
- + + + Configura=C3=A7=C3=A3o + = + + Devido ao fato de o Hibernate ser projetado para operar em v=C3=A1= rios ambientes diferentes, = + h=C3=A1 um grande n=C3=BAmero de par=C3=A2metros de configura=C3= =A7=C3=A3o. Felizmente, a maioria tem valores default = + l=C3=B3gicos e o Hibernate =C3=A9 distribu=C3=ADdo com um arquivo = hibernate.properties = + de exemplo no etc/ que mostra v=C3=A1rias op=C3= =A7=C3=B5es. Apenas coloque o arquivo = + de exemplo no seu classpath e personalize-o. + + + + 1.11 Configura=C3=A7=C3=A3o program=C3=A1tica + + + Uma inst=C3=A2ncia de org.hibernate.cfg.Configuration= + representa um conjunto inteiro de mapeamentos de tipos Java da= aplica=C3=A7=C3=A3o para = + um banco de dados SQL. O Configuration =C3= =A9 usado para construir = + uma SessionFactory (imut=C3=A1vel). Os mape= amentos s=C3=A3o compilados = + a partir de arquivos de mapeamento XML. + + + + + Voc=C3=AA pode obter uma inst=C3=A2ncia Configuration= intanciando- + o diretamente e especificando documentos de mapeamento XML. Se= o arquivo = + de mapeamento est=C3=A3o no classpath, use use addRes= ource(): + + + + + + Uma alternativa (=C3=A0s vezes melhor) =C3=A9 especificar a cl= asse mapeada, = + e permitir que o Hibernate encontre o documento de mapeamento = para voc=C3=AA: = + + + + + + Ent=C3=A3o o Hibernate procurar=C3=A1 pelos arquivos de mapeam= ento chamados = + /org/hibernate/auction/Item.hbm.xml e + /org/hibernate/auction/Bid.hbm.xml no class= path. + Esta abordagem elimina qualquer nome de arquivo de dif=C3=ADci= l compreens=C3=A3o. + + = + + Uma Configuration tamb=C3=A9m permite voc= =C3=AA especificar = + propriedades de configura=C3=A7=C3=A3o: + + + + = + + Este n=C3=A3o =C3=A9 o =C3=BAnico caminho para passar as propr= iedades de configura=C3=A7=C3=A3o = + para o Hibernate. As v=C3=A1rias op=C3=A7=C3=B5es incluem: + + + + + + Passar uma inst=C3=A2ncia de java.util.Proper= ties = + para Configuration.setProperties(). + + + + + Colocar hibernate.properties no dir= et=C3=B3rio = + raiz do classpath. + + + + + Determinar as propriedades do System = + usando java -Dproperty=3Dvalue. + + + + + Include <property> elements in + hibernate.cfg.xml (discussed later). + Incluir elementos <property> = no = + hibernate.cfg.xml (discutido mais t= arde). + + + + + + hibernate.properties =C3=A9 o caminho mais= facil = + se voc=C3=AA quer come=C3=A7ar mais r=C3=A1pido. + + + + O Configuration =C3=A9 entendido como um ob= jeto startup-time, = + =C3=A9 descartado uma vez que a SessionFactory =C3=A9 criada. + + + + = + + Obtendo uma SessionFactory + + + Quando todos os mapeamentos t=C3=AAm sido analisados pelo Configuration, = + a aplica=C3=A7=C3=A3o deve obter uma factory para as inst=C3= =A2ncias da Session. = + O objetivo desta factory =C3=A9 ser compartilhado por todas as= threads da aplica=C3=A7=C3=A3o: + + + + + + Hibernate permite sua aplica=C3=A7=C3=A3o instanciar mais do q= ue uma = + SessionFactory. Isto =C3=A9 =C3=BAtil se vo= c=C3=AA est=C3=A1 usando mais = + do que um banco de dados. + + + + + + Conex=C3=B5es JDBC + + + Normalmente, voc=C3=AA quer mandar criar a SessionFa= ctory criar um + pool de conex=C3=B5es JDBC para voc=C3=AA. Se voc=C3=AA seguir= essa abordagem, a abertura de uma = + Session =C3=A9 t=C3=A3o simples quanto: + + + + + = + + Assim que voc=C3=AA fizer algo que requer o acesso ao banco de= dados, uma = + conex=C3=A3o JDBC ser=C3=A1 obtida do pool. + + + + Para esse trabalho, n=C3=B3s necessitamos passar algumas propr= iedades da conex=C3=A3o JDBC = + para o Hibernate. Todos os nomes de propriedades Hibernate e s= em=C3=A2nticas s=C3=A3o definidas = + org.hibernate.cfg.Environment. N=C3=B3s ire= mos descrever agora = + o mais importantes configura=C3=A7=C3=B5es de conex=C3=A3o JDB= C. + + + + O Hibernate obter=C3=A1 conex=C3=B5es( e pool) usando java.sql.DriverManager + se voc=C3=AA determinar as seguintes propriedades: + + + + Propriedades JDBC Hibernate + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.connection.driver_class + + + Classe driver jdbc + + + + + hibernate.connection.url + + + URL jdbc + + + + + hibernate.connection.username + + + Usu=C3=A1rio do banco de dados + + + + + hibernate.connection.password + + + Senha do usu=C3=A1rio do banco de dados + + + + + hibernate.connection.pool_size + + + N=C3=BAmero m=C3=A1ximo de connecx=C3=B5es n= o pool + + + + +
+ + + O algoritmo de pool de conex=C3=B5es do pr=C3=B3prio Hibernate= entretanto =C3=A9 completamente = + rudimentar. A inten=C3=A7=C3=A3o dele e ajudar a iniciar e n=C3=A3o para usar em um = + sistema de produ=C3=A7=C3=A3o ou at=C3=A9 para test= ar desempenho. Voc=C3=AA deveria usar = + uma ferramente de pool de terceiros para conseguir melhor dese= mpenho e estabilidade. = + Apenas especifique a propriedade hibernate.connection= .pool_size = + com a defini=C3=A7=C3=A3o do pool de conex=C3=B5es. Isto ir=C3= =A1 desligar o pool interno do Hibernate. = + Por exemplo, voc=C3=AA pode gostar de usar C3P0. + + + + O C3P0 =C3=A9 um pool conex=C3=A3o JDBC de c=C3=B3digo aberto = distribu=C3=ADdo junto com = + Hibernate no diret=C3=B3rio lib. O Hi= bernate usar=C3=A1 o = + C3P0ConnectionProvider para o pool de conex= =C3=A3o se = + voc=C3=AA configurar a propriedade hibernate.c3p0.*. Se voc=C3=AA = + gostar de usar Proxool consulte ao pacote hibernate.p= roperties = + e o web site do Hibernate para mais informa=C3=A7=C3=B5es. + + + + Aqui =C3=A9 um exemplo de arquivo hibernate.propertie= s para C3P0: + + + + + + Para usar dentro de um servidor de aplica=C3=A7=C3=A3o, voc=C3= =AA deve configurar = + o Hibernate para obter conex=C3=B5es de um application server = + Datasource registrado no JNDI. Voc=C3=AA ne= cessitar=C3=A1 = + determinar pelo menos uma das seguintes propriedades: + + + + Propriedades do Datasource do Hibernate + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.connection.datasource + + + Nome datasource JNDI + + + + + hibernate.jndi.url + + + URL do fornecedor JNDI (opcional) + + + + + hibernate.jndi.class + + + Classe do JNDI InitialContextFactor= y (opcional) + + + + + hibernate.connection.username + + + Usu=C3=A1rio do banco de dados (o= pcional) + + + + + hibernate.connection.password + + + Senha do usu=C3=A1rio do banco de dados (opcional) + + + + +
+ + + Eis um exemplo de arquivo hibernate.properties para = + um servidor de aplica=C3=A7=C3=A3o fornecedor de datasources J= NDI: + + + + + + Conex=C3=B5es JDBC obtidas de um datasource JNDI ir=C3=A3o aut= omaticamente ir=C3=A3o participar = + das transa=C3=A7=C3=B5es gerenciadas pelo container no servido= r de aplica=C3=A7=C3=A3o. + + + + Arbitrariamente as propriedades de conex=C3=A3o podem ser acre= scentandas ao = + "hibernate.connnection" ao nome da propried= ade. Por exemplo, = + voc=C3=AA deve especificar o charSet usando= hibernate.connection.charSet.t. + + + + Voc=C3=AA pode definir sua pr=C3=B3pria estrat=C3=A9gia de plu= gin para obter conex=C3=B5es JDBC implementando = + a interface org.hibernate.connection.ConnectionProvid= er. Voc=C3=AA pode = + escolher uma implementa=C3=A7=C3=A3o customizada setando hibernate.connection.provider_class. + + +
+ + + Propriedades opcionais de configura=C3=A7=C3=A3o + = + + H=C3=A1 um grande n=C3=BAmero de outras propriedades que contr= olam o comportamento do Hibernate = + em tempo de execu=C3=A7=C3=A3o. Todos s=C3=A3o opcionais e tem= valores default l=C3=B3gicos. + + + + Aviso: algumas destas propriedades s=C3=A3o somente = a "n=C3=ADvel de sistema". + Propriedades n=C3=ADvel de sistema podem ser determinados some= nte via java -Dproperty=3Dvalue + ou hibernate.properties. Elas n= =C3=A3opodem ser = + configuradas por outras t=C3=A9cnicas descritas abaixo. + + + + Hibernate Configuration Properties + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.dialect + + + O nome da classe de um Dialeto = + que permite o Hibernate gerar SQL otimizado pa= ra um banco de = + dados relacional em particular. + + Ex. = + full.classname.of.Dialect + + + + + + hibernate.show_sql + + + Escreve todas as instru=C3=A7=C3=B5es SQL no c= onsole. Esta =C3=A9 uma alternativa = + a configurar a categoria de log org.h= ibernate.SQL + para debug. + + Ex. = + true | false + + + + + + hibernate.format_sql + + + Imprime o SQL formatado no log e console. + + Ex. = + true | false + + + + + + hibernate.default_schema + + + Qualifica no sql gerado, os nome das tabelas s= em qualificar = + com schena/tablespace dado + + Ex. = + SCHEMA_NAME + + + + + + hibernate.default_catalog + + + Qualifica no sql gerado, os nome das tabelas s= em qualificar = + com cat=C3=A1logo dado + + Ex. = + CATALOG_NAME + + + + + + hibernate.session_factory_name + + + O SessionFactory ir=C3=A1 a= utomaticamente = + se ligar a este nome no JNDI depois de ter sid= o criado. + + Ex. = + jndi/composite/name + + + + + + hibernate.max_fetch_depth + + + Estabelece a "profundidade" m=C3=A1xima para = =C3=A1rvore outer join fetch = + para associa=C3=A7=C3=B5es finais =C3=BAnicas(= one-to-one,many-to-one). = + Um 0 desativa por default a= busca outer join. + + eg. = + Valores recomendados entre0 e 3 + + + + + + hibernate.default_batch_fetch_size + + + Determina um tamanho default para busca de ass= ocia=C3=A7=C3=B5es em lotes do Hibernate = + + eg. = + Valores recomendados 4,= 8, = + 16 + + + + + + hibernate.default_entity_mode + + + Determina um modo default para representa=C3= =A7=C3=A3o de entidades = + para todas as sess=C3=B5es abertas desta SessionFactory + + dynamic-map, d= om4j, + pojo + + + + + + hibernate.order_updates + + + For=C3=A7a o Hibernate a ordenar os updates SQ= L pelo valor da chave = + prim=C3=A1ria dos itens a serem atualizados. I= sto resultar=C3=A1 em menos = + deadlocks nas transa=C3=A7=C3=B5es em sistemas= altamente concorrente. + + Ex. = + true | false + + + + + + hibernate.generate_statistics + + + If enabled, Hibernate will collect statistics = useful for + performance tuning. + Se habilitado, o Hibernate coletar=C3=A1 estat= =C3=ADsticas =C3=BAties = + para performance tuning dos bancos. + + Ex. + true | false + + + + + + hibernate.use_identifer_rollback + + + Se habilitado, propriedades identificadoras ge= radas = + ser=C3=A3o zeradas para os valores default qua= ndo os = + objetos forem apagados. + + Ex. + true | false + + + + + + hibernate.use_sql_comments + + + Se ligado, o Hibernate ir=C3=A1 gerar coment= =C3=A1rios dentro do SQL, = + para facilitar o debugging, o valor default = =C3=A9 false. + + eg. + true | false + + + + + +
+ + + JDBC Hibernate e Propriedades de Conex=C3=A3o + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.jdbc.fetch_size + + + Um valor maior que zero determina o tamanho do= fetch = + do JDBC( chamadas Statement.setFetchS= ize()). + + + + + hibernate.jdbc.batch_size + + + Um valor maior que zero habilita uso de batch = updates JDBC2 pelo Hibernate. + + Ex. + valores recomentados entre 5 e 30 + + + + + + hibernate.jdbc.batch_versioned_data + + + Sete esta propriedade como true se seu driver JDBC retorna = + o n=C3=BAmero correto de linhas no ex= ecuteBatch() ( =C3=89 usualmente = + seguro tornar esta op=C3=A7=C3=A3o ligada). O = Hibernate ent=C3=A3o ir=C3=A1 usar betched DML = + para automaticamente versionar dados. false por default. + + Ex. + true | false + + + + + + hibernate.jdbc.factory_class + + + Escolher um Batcher customi= zado. Muitas = + aplica=C3=A7=C3=B5es n=C3=A3o ir=C3=A3o necess= itar desta propriedade de configura=C3=A7=C3=A3o + + Ex. + classname.of.BatcherFactory + + + + + + hibernate.jdbc.use_scrollable_results= et + + + Habilita o uso de JDBC2 scrollable resultsets = pelo Hibernate. + Essa propriedade somente =C3=A9 necessaria qua= ndo se usa Conexe=C3=A7=C3=B5es + JDBC providas pelo usu=C3=A1rio, caso contr=C3= =A1rio o Hibernate os os = + metadados da conex=C3=A3o. + + Ex. = + true | false + + + + + + hibernate.jdbc.use_streams_for_binary= + + + Use streams para escrever/ler tipos b= inary + ou serializable para/a o JD= BC( propriedade a n=C3=ADvel de sistema). + + Ex. + true | false + + + + + + hibernate.jdbc.use_get_generated_keys= + + + Possibilita o uso PreparedStatement.g= etGeneratedKeys() = + do JDBC3 para recuperar chaves geradas nativam= ente depois da inser=C3=A7=C3=A3p. = + Requer driver JDBC3+ e JRE1.4+, determine para= false se seu driver tem = + problemas com gerador de indentificadores Hibe= rnate. Por default, tente = + determinar o driver capaz de usar metadados da= conex=C3=A3o. + + Ex. + true|false + + + + + + hibernate.connection.provider_class + + + O nome da classe de um ConnectionProv= ider personalizado + o qual prover=C3=A1 conex=C3=B5es JDBC para o = Hibernate. + + Ex. = + classname.of.ConnectionProvider + + + + + + hibernate.connection.isolation + + + Determina o n=C3=ADvel de isolamento de uma transa= =C3=A7=C3=A3o JDBC. = + Verifique java.sql.Connection p= ara valores = + siginificativos mas note que a maior parte dos ban= cos de dados = + n=C3=A3o suportam todos os n=C3=ADveis de isolamen= to. + + Ex. = + 1, 2, 4, 8 + + + + + + hibernate.connection.autocommit + + + Habilita autocommit para conex=C3=B5es no pool= JDBC( n=C3=A3o recomendado). + + Ex. + true | false + + + + + + hibernate.connection.release_mode + + + Especifica quando o Hibernate deve liberar con= ex=C3=B5es JDBC. Por default, = + uma conex=C3=A3o JDBC =C3=A9 retida at=C3=A9 a= sess=C3=A3o est=C3=A1 explicitamente fechada = + ou desconectada. Para um datasource JTA do ser= vidor de aplica=C3=A7=C3=A3o, voc=C3=AA deve = + usar after_statement para f= or=C3=A7ar s libera=C3=A7=C3=A3o da conex=C3=B5es = + depois de todas as chamadas JDBC. Para uma con= ex=C3=A3o n=C3=A3o-JTA, freq=C3=BCentemente = + faz sentido liberar a conex=C3=A3o ao fim de c= ada transa=C3=A7=C3=A3o, usando + after_transaction. auto escolheremos + after_statement para as es= trat=C3=A9gias de transa=C3=A7=C3=A3oes JTA e CMT = + e after_transaction para as= estrat=C3=A9gias de transa=C3=A7=C3=A3o JDBC + + Ex. = + auto (default) | on_close | + after_transaction | after_statement + + + Note that this setting only affects Sessions returned from + SessionFactory.openSession. For Sessions + obtained through SessionFactory.g= etCurrentSession, the + CurrentSessionContext i= mplementation configured for use + controls the connection release mode for t= hose Sessions. + See + + + + + + hibernate.connection.<proper= tyName> + + + Passa a propriedade JDBC propertyName = + para DriverManager.getConnection(). + + + + + hibernate.jndi.<property= Name> + + + Passar a propriedade propertyName para = + o InitialContextFactory JND= I. + + + + +
+ + + Propriedades de Cach=C3=AA do Hibernate + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.cache.provider_class + + + O nome da classe de um CacheProvider<= /literal> customizado. + + Ex. = + classname.of.CacheProvider + + + + + + hibernate.cache.use_minimal_puts + + + Otimizar opera=C3=A7=C3=A3o de cach=C3=AA de s= egundo n=C3=ADvel para minimizar escritas, = + ao custo de leituras mais frequantes. Esta con= figura=C3=A7=C3=A3o =C3=A9 mais =C3=BAtil = + para cach=C3=AAs clusterizados e, no Hibernate= 3, =C3=A9 habilitado por default = + para implementa=C3=A7=C3=B5es de cach=C3=AA cl= usterizar. + + Ex. = + true|false + + + + + + hibernate.cache.use_query_cache + + + Habilita a cache de consultas, Mesmo assim, co= nsultas individuais ainda tem que ser = + habilitadas para o cache. + + Ex. = + true|false + + + + + + hibernate.cache.use_second_level_cach= e + + + Pode ser usada para desabilitar completamente = ocache de segundo n=C3=ADvel, = + o qual est=C3=A1 habilitado por default para c= lasses que especificam = + um mapeamento <cache>. + + + Ex. = + true|false + + + + + + hibernate.cache.query_cache_factory + + + O nome de uma classe que implementa a interfac= e = + QueryCache personalizada, p= or = + default, um StandardQueryCache + criado automaticamente. + + Ex. + classname.of.QueryCache + + + + + + hibernate.cache.region_prefix + + + Um prefixo para usar nos nomes da =C3=A1rea es= pecial = + do cach=C3=AA de segundo n=C3=ADvel. + + Ex. = + prefix + + + + + + hibernate.cache.use_structured_entrie= s + + + Forces Hibernate to store data in the second-l= evel cache + in a more human-friendly format. + For=C3=A7a o Hibernate armazenar dados no cach= =C3=AA se segundo = + n=C3=ADvel em um formato mais legivel. + + Ex. + true|false + + + + + +
+ + + Propriedades de Transa=C3=A7=C3=A3o do Hibernate + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.transaction.factory_class + + + O nome da clase de um a TransactionFa= ctory + para usar com API Transaction + ( por default JDBCTransactionFactory). + + Ex. = + classname.of.TransactionFactory + + + + + + jta.UserTransaction + + + Um nome JNDI usado pelo JTATransactio= nFactory = + para obter uma UserTransaction JTA a partir = + do servidor de aplica=C3=A7=C3=A3o. + + Ex. = + jndi/composite/name + + + + + + hibernate.transaction.manager_lookup_= class + + + O nome da classe de um TransactionMan= agerLookup + =E2=80=93 requerido quando caching a n=C3=ADve= l JVM esta habilitado ou quando = + estivermos usando um generator hilo em um ambi= ente JTA. + + Ex. = + classname.of.TransactionManagerLo= okup + + + + + + hibernate.transaction.flush_before_co= mpletion + + + Se habilitado, a sess=C3=A3o ser=C3=A1 automat= icamente limpa antes da fase de = + conclus=C3=A3o da transa=C3=A7=C3=A3o. =C3=89 = preferivel a ger=C3=AAncia interna e = + autom=C3=A1tica do contexto da sess=C3=A3o, ve= ja + + + Ex. = + true | false + + + + + + hibernate.transaction.auto_close_sess= ion + + + Se habilitado, a sess=C3=A3o ser=C3=A1 automat= icamente fechada ap=C3=B3s a fase de + conclus=C3=A3o da transa=C3=A7=C3=A3o. =C3=89= preferivel a ger=C3=AAncia interna e = + autom=C3=A1tica do contexto da sess=C3=A3o, ve= ja + + + Ex. = + true | false + + + + + +
+ + + Propriedades Variadas + + + + + + Nome da Propriedade + Prop=C3=B3sito + + + + + + hibernate.current_session_context_cla= ss + + + Forne=C3=A7e uma estrat=C3=A9gia (personalizad= a) para extens=C3=A3o = + da Session "corrente". Veja = + para = + mais informa=C3=A7=C3=A3o sobre estrat=C3=A9g= ias internas. + + Ex. + jta | thread | + managed | cust= om.Class + + + + + + hibernate.query.factory_class + + + Escolha a implementa=C3=A7=C3=A3o de an=C3=A1l= ise HQL. + + eg. = + org.hibernate.hql.ast.ASTQueryTra= nslatorFactory or + org.hibernate.hql.classic.Classic= QueryTranslatorFactory + + + + + + hibernate.query.substitutions + + + Mapeamento a partir de s=C3=ADmbolos em consul= tas HQL para = + s=C3=ADmbolos SQL( s=C3=ADmbolos devem ser fun= =C3=A7=C3=B5es ou nome literais + , por exemplo). + + eg. = + hqlLiteral=3DSQL_LITERAL, hqlFunc= tion=3DSQLFUNC + + + + + + hibernate.hbm2ddl.auto + + + Automaticamente valida ou exporta schema DDL p= ara o banco de = + dados quando o SessionFactory =C3=A9 criads. + Com create-drop, o schema d= o banco de dados = + ser=C3=A1 excluido quando a create-dr= op for + fechada esplicitamente. + + Ex. = + validate | upd= ate | = + create | creat= e-drop + + + + + + hibernate.cglib.use_reflection_optimi= zer + + + Habilita o uso de CGLIB em vez de reflex=C3=A3= o em tempo de execu=C3=A7=C3=A3o + ( propriedade a n=C3=ADvel de sistema). Reflex= =C3=A3o pode algumas vezes ser =C3=BA + til quando controlar erros, note que o Hiberna= te sempre ir=C3=A1 requerer a CGLIB = + mesmo se voc=C3=AA desligar o otimizador. Voc= =C3=AA n=C3=A3o pode determinar esta = + propriedade no hibernate.cfg.xml. + + Ex. = + true | false + + + + + +
+ + + Dialetos SQL + + + Voc=C3=AA deve sempre determinar a propriedade hi= bernate.dialect = + para a subclasse de org.hibernate.dialect.Dialect= correta de seu = + banco de dados. Se voc=C3=AA especificar um dialeto, Hiber= nate usar=C3=A1 defaults l=C3=B3gicos = + para qualquer um das outras propriedades listadas abaixo, = reduzindo o esfor=C3=A7o de = + especific=C3=A1-los manualmente. = + + + + Hibernate SQL Dialects (<literal>hibernate.dialect<= /literal>) + + + + + + RDBMS + Dialect + + + + + DB2 org.hiberna= te.dialect.DB2Dialect + + + DB2 AS/400 org.= hibernate.dialect.DB2400Dialect + + + DB2 OS390 org.h= ibernate.dialect.DB2390Dialect + + + PostgreSQL org.= hibernate.dialect.PostgreSQLDialect + + + MySQL org.hiber= nate.dialect.MySQLDialect + + + MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect + + + MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect + + + Oracle (any version) org.hibernate.dialect.OracleDialect + + + Oracle 9i/10g o= rg.hibernate.dialect.Oracle9Dialect + + + Sybase org.hibe= rnate.dialect.SybaseDialect + + + Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect + + + Microsoft SQL Server org.hibernate.dialect.SQLServerDialect + + + SAP DB org.hibe= rnate.dialect.SAPDBDialect + + + Informix org.hi= bernate.dialect.InformixDialect + + + HypersonicSQL o= rg.hibernate.dialect.HSQLDialect + + + Ingres org.hibe= rnate.dialect.IngresDialect + + + Progress org.hi= bernate.dialect.ProgressDialect + + + Mckoi SQL org.h= ibernate.dialect.MckoiDialect + + + Interbase org.h= ibernate.dialect.InterbaseDialect + + + Pointbase org.h= ibernate.dialect.PointbaseDialect + + + FrontBase org.h= ibernate.dialect.FrontbaseDialect + + + Firebird org.hi= bernate.dialect.FirebirdDialect + + + +
+ +
+ + + Recupera=C3=A7=C3=A3o por uni=C3=A3o externa (Outer Joi= n Fetching) + + + Se seu banco de dados suporta Recupera=C3=A7=C3=A3o por un= i=C3=A3o externa (Outer Join Fetching) no estilo ANSI, = + Oracle ou Sybase, A recupera=C3=A7=C3=A3o por uni=C3=A3o e= xterna (Outer Join Fetching) frequentemente aumentar=C3=A1 + o desempenho limitando o n=C3=BAmero de chamadas (round tr= ips) ao banco de dados( ao custo de = + possivelmente mais trabalho desempenhado pelo pr=C3=B3prio= banco de dados). A recupera=C3=A7=C3=A3o por = + uni=C3=A3o externa (Outer Join Fetching)permite um gr=C3= =A1fico completo de objetos conectados = + por muitos-para-um, um-para-muitos, muitos-para-muitos e a= ssocia=C3=A7=C3=B5es um-para-um para ser = + recuperadas em um simples instru=C3=A7=C3=A3o SQL SELECT . + + + + + A recupera=C3=A7=C3=A3o por uni=C3=A3o externa (Outer Join= Fetching) pode ser desabilitado = + globalmente setando a propriedade = + hibernate.max_fetch_depth para 0. = + Uma valor 1 ou maior habilita o outer join fetching para a= ssocia=C3=A7=C3=B5es um-para-um = + e muitos-para-umos cujos quais tem sido mapeado com fetch=3D"join". + + + + Veja para mais in= forma=C3=A7=C3=B5es. + + + + + + Fluxos Bin=C3=A1rios (Binary Streams) + + + O Oracle limita o tamanho de arrays de byte que pode ser = + passado para/de o driver JDBC. Se voc=C3=AA desejar usar g= randes inst=C3=A2ncias de = + tipos binary ou serializable<= /literal>, voc=C3=AA = + deve habilitar hibernate.jdbc.use_streams_for_bin= ary. + Essa =C3=A9 uma configura=C3=A7=C3=A3o que s=C3= =B3 pode ser feita a n=C3=ADvel de sistema. + + + + + + Cach=C3=AA de segundo n=C3=ADvel e query + + + As propriedades prefixadas pelo hibernate.cache = + permite voc=C3=AA usar um sistema de cach=C3=AA de segundo= n=C3=ADvel = + em um processo executado em clustercom Hibernate. = + Veja para mais detal= hes. + + + + + + Substitui=C3=A7=C3=B5es na Linguagem de Consulta + + + Voc=C3=AA pode definir novos s=C3=ADmbolos de consulta Hib= ernate usando = + hibernate.query.substitutions. = + Por exemplo: + + + hibernate.query.substitutions true=3D1, false= =3D0 + + + Faria com que os s=C3=ADmbolos true e <= literal>false = + passasem a ser traduzidos para literais inteiro no SQL ger= ado. + + + hibernate.query.substitutions toLowercase=3DLO= WER + + + permitir=C3=A1 voc=C3=AA renomear a fun=C3=A7=C3=A3o LOWER no SQL. + + + + + + Estat=C3=ADsticas do Hibernate + + + If you enable hibernate.generate_statistics, Hibernate will = + expose a number of metrics that are useful when tuning a r= unning system via + SessionFactory.getStatistics(). Hiberna= te can even be configured + to expose these statistics via JMX. Read the Javadoc of th= e interfaces in + org.hibernate.stats for more informatio= n. + = + Se voc=C3=AA habilitar hibernate.generate_statist= ics, o Hibernate = + exibir=C3=A1 um n=C3=BAmero de m=C3=A9tricas bastante =C3= =BAtil ao ajustar um sistema via + SessionFactory.getStatistics(). O Hiber= nate pode at=C3=A9 ser = + configurado para exibir essas estat=C3=ADsticas via JMX. L= eia o Javadoc da interface + org.hibernate.stats para mais informa= =C3=A7=C3=B5es. + + + +
+ + + Logging + + + Hibernate registra v=C3=A1rios eventos usando Apache commons-l= ogging. + + + + O servi=C3=A7o commons-logging direcionar=C3=A1 a sa=C3=ADda p= ara o Apache Log4j + ( se voc=C3=AA incluir log4j.jarr no seu cl= asspath) ou = + JDK1.4 logging( se estiver em uso JDK1.4 ou maior). Voc=C3=AA = pode fazer o = + download do Log4j a partir de http://jakarta.apache.= org. + Para usar Log4j voc=C3=AA necessitar=C3=A1 colocar um arquivo = + log4j.properties no seu classpath, um exemp= lo de arquivo + de propriedades =C3=A9 distribu=C3=ADdo com o Hibernate no dir= et=C3=B3rio = + src/. + + + = + + We strongly recommend that you familiarize yourself with Hiber= nate's log + messages. A lot of work has been put into making the Hibernate= log as + detailed as possible, without making it unreadable. It is an e= ssential + troubleshooting device. The most interesting log categories ar= e the + following: + = + N=C3=B3s recomendamos enfaticamente que voc=C3=AA se familiari= ze-se com mensagens de = + log do Hibernate. Uma parte do trabalho tem sido posto em faze= r o log = + Hibernate t=C3=A3o detalhado quanto poss=C3=ADvel, sem faz=C3= =AA-lo ileg=C3=ADvel. = + =C3=89 um essencial dispositivos de controle de erros. As cate= gorias de log = + mais interessantes s=C3=A3o as seguintes: + + = + + Categorias de Log do Hibernate + + + + + + Categoria + Fun=C3=A7=C3=A3o + + + + + org.hibernate.SQL + Registra todas as instru=C3=A7=C3=B5es = SQL DML a medida que elas s=C3=A3o executadas + + + org.hibernate.type + Registra todos os par=C3=A2metros JDBC<= /entry> + + + org.hibernate.tool.hbm2ddl + Registra todas as instru=C3=A7=C3=B5es = SQL DDL a medida que elas s=C3=A3o executadas + + + org.hibernate.pretty= + + Log the state of all entities (max 20 enti= ties) associated + with the session at flush time + Registra o estado de todas as entidades (m= =C3=A1ximo 20 entidades) = + associadas a session no momento da limpeza= (flush). + + + + org.hibernate.cache<= /entry> + Registra todas as atividades de cach=C3= =AA de segundo n=C3=ADvel + + + org.hibernate.transaction + Registra atividades relacionada a trans= a=C3=A7=C3=A3o + + + org.hibernate.jdbc + Registra todas as requisi=C3=A7=C3=B5es= de recursos JDBC + + + org.hibernate.hql.ast.AST + + Registra instru=C3=A7=C3=B5es SQL e HQL du= rante a an=C3=A1lise da consultas + + + + org.hibernate.secure= + Registra todas as requisi=C3=A7=C3=B5es= de autoriza=C3=A7=C3=A3o JAAS + + + org.hibernate + + Registra tudo ( uma parte das informa=C3= =A7=C3=B5es, mas muito = + =C3=BAtil para controle de erros ) + + + + +
+ = + + Quando desenvolver aplica=C3=A7=C3=B5es com Hibernate, voc=C3= =AA deve quase sempre trabalhar com = + debug debug para a categoria org.= hibernate.SQL, = + ou, alternativamente, a com a propriedade hibernate.s= how_sql habilitada. + + = + = +
+ + + Implementado uma <literal>NamingStrategy</literal> + + + A interface org.hibernate.cfg.NamingStrategy permite voc=C3=AA = + especificar um "padr=C3=A3o de nomea=C3=A7=C3=A3o" para objeto= s do banco de dados e elementos schema. + + + + Voc=C3=AA deve criar regras para a gera=C3=A7=C3=A3o automatic= amente de identificadores = + do banco de dados a partir de identificadores Java ou para pro= cessar = + colunas "computadas" e nomes de tabelas dado o arquivo de mape= amento = + para nomes "f=C3=ADsicos" de tabelas e colunas. Esta caracter= =C3=ADstica ajuda a = + reduzir a verbosidade do documento de mapeamento, eliminando i= nterfer=C3=AAncias = + repetitivas( TBL_prefixos, por exemplo). A = estrat=C3=A9gia = + default usada pelo Hibernate =C3=A9 completamente m=C3=ADnima. + + + + Voc=C3=AA pode especificar uma estrat=C3=A9gia diferente ao ch= amar = + Configuration.setNamingStrategy() antes de = adicionar = + os mapeamentos: + + + + = + + org.hibernate.cfg.ImprovedNamingStrategy = =C3=A9 uma estrat=C3=A9gia = + interna que pode ser um ponto de come=C3=A7o =C3=BAtil para al= gumas aplica=C3=A7=C3=B5es. + + + + + + Arquivo de configura=C3=A7=C3=A3o XML + + + Uma maneira alternativa de configura=C3=A7=C3=A3o =C3=A9 espec= ificar uma configura=C3=A7=C3=A3o completa = + em um arquivo chamado hibernate.cfg.xml. Es= te arquivo pode = + ser usado como um substituto para o arquivo hibernate= .properties = + ou, se ambos est=C3=A3o presentes, sobrescrever propriedades. + + + + The XML configuration file is by default expected to be in the= root o + your CLASSPATH. Here is an example: + O arquivo XML de configura=C3=A7=C3=A3o =C3=A9 por default esp= erado para estar na = + raiz do seu CLASSPATH. Veja um exemplo: + + + + + + + + + + + + java:/comp/env/jdbc/MyDB<= /property> + org.hibernate.dialect.MySQLDialect + false + + org.hibernate.transaction.JTATransactionFactory + + java:comp/UserTransaction + + + + + + + + + + + + +]]> + + + Como voc=C3=AA pode ver, a vantagem deste enfoque =C3=A9 a ext= ernaliza=C3=A7=C3=A3o dos nomes dos = + arquivos de mapeamento para configura=C3=A7=C3=A3o. O hibernate.cfg.xml = + tamb=C3=A9m =C3=A9 mais conveniente caso voc=C3=AA tenha que a= justar o cache do Hibernate. = + Note que a escolha =C3=A9 sua em usar hibernate.pro= perties ou + hibernate.cfg.xml, ambos s=C3=A3o equivalen= te, =C3=A0 exce=C3=A7=C3=A3o dos benef=C3=ADcios = + acima mencionados de usar a sintaxe de XML. + + + + Com a configura=C3=A7=C3=A3o do XML, iniciar o Hibernate =C3=A9= ent=C3=A3o t=C3=A3o simples como + + + + + + You can pick a different XML configuration file using + + + + + + + + Integra=C3=A7=C3=A3o com servidores de aplica=C3=A7=C3=A3o = J2EE + + + O Hibernate tem os seguintes pontos da integra=C3=A7=C3=A3o pa= ra o infraestrutura de J2EE: + + + + + + DataSources gerenciados pelo container: O Hibernate pode = + usar conex=C3=B5es JDBC gerenciadas pelo Container e forne= cidas pela JNDI. Geralmente, = + um TransactionManager compat=C3=ADvel c= om JTA e um = + ResourceManager cuidam do gerenciamento= da transa=C3=A7=C3=A3o ( CMT ), = + especialmente em transa=C3=A7=C3=B5es distribu=C3=ADdas ma= nipuladas atrav=C3=A9s de v=C3=A1rios DataSources. = + Naturalmente, voc=C3=AA tamb=C3=A9m pode demarcar os limit= es das transa=C3=A7=C3=B5es programaticamente (BMT) = + ou voc=C3=AA poderia querer usar a API opcional do Hiberna= te Transaction + para esta manter seu c=C3=B3digo port=C3=A1vel. + + + + + + + + Liga=C3=A7=C3=A3o (binding) autom=C3=A1tica a JN= DI: O Hibernate pode = + associar sua SessionFactory a JNDI depo= is de iniciado. + + + + + + + + Liga=C3=A7=C3=A3o (binding) Session na JTA: = + A Session do Hibernate pode automaticam= ente ser ligada = + ao escopo da transa=C3=A7=C3=B5es JTA. Simplesmente locali= zando a SessionFactory = + da JNDI e obtendo aSession corrente. De= ixe o Hibernate cuidar = + da limpeza e encerramento da Session qu= ando as transa=C3=A7=C3=B5es JTA = + terminarem. A Demarca=C3=A7=C3=A3o de transa=C3=A7=C3=A3o = pode ser declarativa (CMT) ou = + program=C3=A1tica(BMT/Transa=C3=A7=C3=A3o do usu=C3=A1rio). + + + + + + + + JMX deployment: Se voc=C3=AA usa um J= MX servidor de = + aplica=C3=A7=C3=B5es capaz (ex. Jboss AS), voc=C3=AA pode = fazer a insta=C3=A7=C3=A3o do Hibernate = + como um Mbean controlado. Isto evita ter que iniciar uma l= inha de = + c=C3=B3digo para construir sua SessionFactory de uma = + Configuration. O container iniciar=C3= =A1 seu = + HibernateService, e idealmente tamb=C3= =A9m cuidar=C3=A1 = + das depend=C3=AAncias de servi=C3=A7os (DataSources, t=C3= =AAm que estar dispon=C3=ADveis = + antes do Hibernate iniciar, etc.). + + + + + + Dependendo em seu ambiente, voc=C3=AA poderia ter que ajustar= a op=C3=A7=C3=A3o de configura=C3=A7=C3=A3o = + hibernate.connection.aggressive_release par= a verdadeiro ( true ), = + se seu servidor de aplica=C3=A7=C3=B5es lan=C3=A7ar exe=C3=A7= =C3=B5es "reten=C3=A7=C3=A3o de conec=C3=A7=C3=A3o". + + + + Configura=C3=A7=C3=A3o de estrat=C3=A9gia de transa=C3= =A7=C3=A3o + + + A API Hibernate Session =C3=A9 independ= ente de qualquer sistema de = + demarca=C3=A7=C3=A3o de transa=C3=A7=C3=A3o em sua arquite= tura. Se voc=C3=AA deixar o Hibernate usar = + a JDBC diretamente, atrav=C3=A9s de um pool de conex=C3=B5= es, voc=C3=AA pode inicializar e = + encerrar suas transa=C3=A7=C3=B5es chamando a API JDBC. S= e voc=C3=AA rodar em um servidor de = + aplica=C3=A7=C3=B5es J2EE, voc=C3=AA poder=C3=A1 usar tran= sa=C3=A7=C3=B5es controladas por beans e chamar = + a API JTA e UserTransaction quando nece= ss=C3=A1rio. + + + + + Para manter seu c=C3=B3digo port=C3=A1vel entre estes dois= ( e outros ) ambientes, recomendamos = + a API Hibernate Transaction, que envolv= e e esconde o sistema subjacente. = + Voc=C3=AA tem que especificar um classe construtora para <= literal>Transaction instanciar = + ajustando a propriedade de configura=C3=A7=C3=A3o do hibernate.transaction.factory_class. + + + + + Existem tr=C3=AAs escolhas (internas) padr=C3=B5es: + + + + + org.hibernate.transaction.JDBCTransacti= onFactory + + delegada as transa=C3=A7=C3=B5es (JDBC)a bas= es de dados (Padr=C3=A3o) + = + + + + org.hibernate.transaction.JTATransactio= nFactory + + + delegada a transa=C3=A7=C3=A3o a um container = gerenciador se a transa=C3=A7=C3=A3o = + existente estiver de acordo neste contexto (ex= : m=C3=A9todo bean sess=C3=A3o EJB), = + se n=C3=A3o uma nova transa=C3=A7=C3=A3o =C3= =A9 iniciada e uma transa=C3=A7=C3=A3o controlado por = + um bean =C3=A9 usada. + + + + + org.hibernate.transaction.CMTTransactio= nFactory + + delega para um container gerenciador de tran= sa=C3=A7=C3=B5es JTA + + + + + + Voc=C3=AA tamb=C3=A9m pode definir suas pr=C3=B3prias estr= at=C3=A9gias de transa=C3=A7=C3=A3o ( para um servi=C3=A7o de = + transa=C3=A7=C3=A3o CORBA por exemplo). + + + + Algumas caracter=C3=ADsticas no Hibernate (ex., o cache de= segundo n=C3=ADvel, sess=C3=B5es contextuais = + com JTA, etc.) requerem acesso a JTA TransactionM= anager em um ambiente = + controlado. Em um servidor de aplica=C3=A7=C3=A3o voc=C3= =AA tem que especificar como o Hibernate pode = + obter uma refer=C3=AAncia para a TransactionManag= er, pois o J2EE n=C3=A3o = + padronize um mecanismo simples : + + + + Gerenciadores de transa=C3=A7=C3=B5es JTA + + + + + + Transaction Factory + Application Server + + + + + org.hibernate.transaction.JBos= sTransactionManagerLookup + JBoss + + + org.hibernate.transaction.Webl= ogicTransactionManagerLookup + Weblogic + + + org.hibernate.transaction.WebS= phereTransactionManagerLookup + WebSphere + + + org.hibernate.transaction.WebS= phereExtendedJTATransactionLookup + WebSphere 6 + + + org.hibernate.transaction.Orio= nTransactionManagerLookup + Orion + + + org.hibernate.transaction.Resi= nTransactionManagerLookup + Resin + + + org.hibernate.transaction.JOTM= TransactionManagerLookup + JOTM + + + org.hibernate.transaction.JOnA= STransactionManagerLookup + JOnAS + + + org.hibernate.transaction.JRun= 4TransactionManagerLookup + JRun4 + + + org.hibernate.transaction.BEST= ransactionManagerLookup + Borland ES + + + +
+ +
+ + + <literal>SessionFactory</literal> ligada a JNDI + + + Uma SessionFactory de Hibernate ligada = a JNDI pode simplificar + a localiza=C3=A7=C3=A3o da fabrica e a cria=C3=A7=C3=A3o d= e novas Sessions. + Observe que isto n=C3=A3o relacionado a um Dataso= urce ligado = + a JNDI, simplemente ambos usam o mesmo registro! + + + + If you wish to have the SessionFactory = bound to a JNDI namespace, specify + a name (eg. java:hibernate/SessionFactory) using the property + hibernate.session_factory_name. If this= property is omitted, the + SessionFactory will not be bound to JND= I. (This is especially useful in + environments with a read-only JNDI default implementation,= e.g. Tomcat.) + + + + When binding the SessionFactory to JNDI= , Hibernate will use the values of + hibernate.jndi.url, hibernate.= jndi.class to instantiate + an initial context. If they are not specified, the default= InitialContext + will be used. + + + + Hibernate will automatically place the SessionFac= tory in JNDI after + you call cfg.buildSessionFactory(). Thi= s means you will at least have + this call in some startup code (or utility class) in your = application, unless you use + JMX deployment with the HibernateService (discussed later). + + + + If you use a JNDI SessionFactory, an EJ= B or any other class may + obtain the SessionFactory using a JNDI= lookup. + + + + We recommend that you bind the SessionFactory to JNDI in + a managend environment and use a static= singleton otherwise. + To shield your application code from these details, we als= o 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. + + + + + + Current Session context management with JTA + + + The easiest way to handle Sessions and = transactions is + Hibernates automatic "current" Session = management. + See the discussion of current sessions. + Using the "jta" session context, if the= re 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 Sessions + retrieved via getCurrentSession() in "jta" context + will be set to automatically flush before the transaction com= pletes, close + after the transaction completes, and aggressively release JDB= C connections + after each statement. This allows the Sessions 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 cod= e 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, decla= rative transaction + demarcation with CMT is preferred. + + + + + + JMX deployment + + + The line cfg.buildSessionFactory() stil= l has to be executed + somewhere to get a SessionFactory into = JNDI. You can do this + either in a static initializer block (l= ike the one in + HibernateUtil) or you deploy Hibernate = as a managed + service. + + + + Hibernate is distributed with org.hibernate.jmx.H= ibernateService + for deployment on an application server with JMX capabilit= ies, such as JBoss AS. + The actual deployment and configuration is vendor specific= . Here is an example + jboss-service.xml for JBoss 4.0.x: + + + + + + + + + jboss.jca:service=3DRARDeployer + jboss.jca:service=3DLocalTxCM,name=3DHsqlDS + + + java:/hibernate/SessionFactory + + + java:HsqlDS + org.hibernate.dialect.HSQLDialect + + + + org.hibernate.transaction.JTATransactionFactory + + org.hibernate.transaction.JBossTransactionManagerLookup + true + true + + + 5 + + + true + org.hibernate.cache.EhCacheProv= ider + true + + + true + + + auction/Item.hbm.xml,auction/Category= .hbm.xml + + + +]]> + + + This file is deployed in a directory called META-= INF and packaged + in a JAR file with the extension .sar (= service archive). You also need + to package Hibernate, its required third-party libraries, = your compiled persistent classes, + as well as your mapping files in the same archive. Your en= terprise beans (usually session + beans) may be kept in their own JAR file, but you may incl= ude this EJB JAR file in the + main service archive to get a single (hot-)deployable unit= . Consult the JBoss AS + documentation for more information about JMX service and E= JB deployment. + + + + +
+ +
+ Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ev= ents.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.x= ml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/events.x= ml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Interceptadores e Eventos = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ex= ample_mappings.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= mappings.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= mappings.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Exemplo: V=C3=A1rios Mapeamentos = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ex= ample_parentchild.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= parentchild.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= parentchild.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Example: Parent/Child = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/ex= ample_weblog.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= weblog.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/example_= weblog.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Example: Weblog Application = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/fi= lters.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.= xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/filters.= xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Filtrando dados = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/in= heritance_mapping.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inherita= nce_mapping.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/inherita= nce_mapping.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Mapeamento de Heran=C3=A7a = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/pe= rformance.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performa= nce.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/performa= nce.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Aumentando a performance = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/pe= rsistent_classes.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persiste= nt_classes.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/persiste= nt_classes.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Persistent Classes = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/pr= eface.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.= xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/preface.= xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Pref=C3=A1cio = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/qu= ery_criteria.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_cr= iteria.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_cr= iteria.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Consultas por crit=C3=A9rios = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/qu= ery_hql.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hq= l.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_hq= l.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,1163 +1,1174 @@ = -=EF=BB=BF - HQL: A linguagem de Queries do Hibernate - = - - O Hibernate vem com uma poderosa linguagem que =C3=A9 (intencional= mente) muito parecida = - com o SQL. Mas n=C3=A3o seja enganado pela sintaxe; a HQL =C3=A9 t= otalmente orientada =C3=A0 objetos, = - requer conhecimentos de heran=C3=A7a, polimorfismo e associa=C3=A7= =C3=B5es. = - - - - Case Sensit=C3=ADve - - - As Queries n=C3=A3o s=C3=A3o case-sensitive, exceto pelo nomes= das classes e propriedades Java. = - sELEct e o mesmo que = - SELECT mas - org.hibernate.eg.FOO n=C3=A3o =C3=A9 - org.hibernate.eg.Foo e - foo.barSet n=C3=A3o =C3=A9 - foo.BARSET. - = - - = - - Esse manual usa as palavras chave HQL em letras min=C3=BAscula= s. Alguns usu=C3=A1rios acham que = - com letras mai=C3=BAsculas as queries ficam mais leg=C3=ADveis= , mas n=C3=B3s achamos essa conven=C3=A7=C3=A3o feia = - dentro do c=C3=B3digo Java. - - = - - - - A clausula from - - - A mais simples query poss=C3=ADvel do Hibernate =C3=A9 a assim: - - = - - = - - Ela ir=C3=A1 retornar todas as instancias da classe e= g.Cat. - Necessariamente n=C3=A3o precisamos qualificar o nome da class= e, pois =C3=A9 realizado = - auto-import por padr=C3=A3o. Por isso na ma= ior parte do tempos = - n=C3=B3s simplesmente escrevemos: - - = - - = - - Na maior parte do tempo, voc=C3=AA precisar=C3=A1 atribuir um = alias, = - desde que voc=C3=AA queira se referia ao Cat em outras partes da = - query. - - - - - - Essa query atribui um alias a cat para as i= nstancias de = - Cat, ent=C3=A3o n=C3=B3s podemos usar esse = alias depois na query. = - A palavra chave as =C3=A9 opcional; poder=C3=ADamos escrever a= ssim: - - = - - = - - M=C3=BAltiplas classes pode ser envolvidas, resultando em um p= roduto cartesiano ou "cross" join. - - = - - - = - - =C3=89 considerada uma boa pr=C3=A1tica os nomes dos aliases c= ome=C3=A7arem com letra min=C3=BAscula, = - aderente com os padr=C3=B5es Java para vari=C3=A1veis locais (= ex: domesticCat). - - = - - - - Associa=C3=A7=C3=B5es e joins - - - N=C3=B3s tamb=C3=A9m podemos querer atribuir aliases em uma en= tidade associada, ou mesmo = - em elementos de uma cole=C3=A7=C3=A3o de valores, usando um join. - - - - - - - - - - Os tipos de joins suportados foram inspirados no SQL ANSI: - - - - - - inner join - - - - - left outer join - - - - - right outer join - - - - - full join (geralmente n=C3=A3o =C3= =A9 =C3=BAtil) - - - - = - - The inner join, left outer join and = - right outer join constructs may be abbrevia= ted. - As constru=C3=A7=C3=B5es inner join, left outer join e - right outer join podem ser abreviadas. = = - - - - = - - Voc=C3=AA pode fornecer condi=C3=A7=C3=B5es extras de join usa= ndo a palavra = - chave do HQL with. - - - with kitten.bodyWeight > 10.0]]> - - - Adicionalmente, um "fetch" join permite que associa=C3=A7=C3= =B5es ou cole=C3=A7=C3=B5es de valores = - sejam inicializadas junto com o objeto pai, usando apenas um s= elect. Isso =C3=A9 = - muito =C3=BAtil no caso das cole=C3=A7=C3=B5es. Isso efetivame= nte sobre escreve as declara=C3=A7=C3=B5es - outer join e lazy do arquivo mapeamento para associa=C3=A7=C3= =B5es e cole=C3=A7=C3=B5es. - Veja a se=C3=A7=C3=A3o para mais informa=C3=A7=C3=B5es. - - = - fetchcat.mate - left join fetchcat.kittens]]> - = - - Usualmente, um fetchjoin n=C3=A3o precisa a= tribuir um alias, pois o objeto associado n=C3=A3o = - deve ser usado na clausula where (ou em qua= lquer outra clausula). = - Tamb=C3=A9m, os objetos associados n=C3=A3o s=C3=A3o retornado= s diretamente nos resultados da query. = - Ao inv=C3=A9s disso, eles devem ser acessados usando o objeto = pai. A =C3=BAnica raz=C3=A3o que n=C3=B3s = - podemos necessitar de um alias =C3=A9 quando fazemos um fech j= oin recursivamente em uma = - cole=C3=A7=C3=A3o adicional: - - = - fetchcat.mate - left join fetchcat.kittens child - left join fetchchild.kittens]]> - = - - Observe que a constru=C3=A7=C3=A3o fetch n= =C3=A3o deve ser usada em queries invocadas usando = - iterate() (embora possa ser usado com scroll()). O = - fetch tamb=C3=A9m n=C3=A3o deve ser usado j= unto com o setMaxResults() ou = - setFirstResult() pois essas opera=C3=A7=C3= =B5es s=C3=A3o baseadas nas linhas retornadas, que = - normalmente contem duplicidade devido ao fetching das cole=C3= =A7=C3=B5es, ent=C3=A3o o n=C3=BAmero de linhas pode n=C3=A3o = - ser o que voc=C3=AA espera. = - = - O fetch n=C3=A3o deve ser usado junto com u= ma condi=C3=A7=C3=A3o with em = - uma condi=C3=A7=C3=A3o with ad hoc. =C3=89 = poss=C3=ADvel que seja criado um produto cartesiano pelo = - join fetching em mais do que uma cole=C3=A7=C3=A3o em uma quer= y, ent=C3=A3o tome cuidado nesses casos. Um join = - fetching em varias cole=C3=A7=C3=B5es pode trazer resultados i= nesperados para mapeamentos do tipo bag, tome = - cuidado na hora de formular queries como essas. Finalmente, ob= serve o seguinte, o = - full join fetch e right join fetch= n=C3=A3o s=C3=A3o significativos. - - = - - = - Se est=C3=A1 usando o n=C3=ADvel de propriedade lazy (com instrumenta=C3=A7=C3=A3o de bytecode), =C3=A9 poss=C3=ADvel = - for=C3=A7ar o Hibernate a buscar as propri= edades lazy imediatamente (na primeira query), = - usando fetch all properties . = - - = - fetchall= properties order by name]]> - fetchall properties where lower(doc.name) like '%cats%']]> - - - - - Formas e sintaxe de joins - - - O HQL suporta duas formas de associa=C3=A7=C3=A3o para uni=C3=A3o: <= literal>impl=C3=ADcita e explicita. - - - - As queries apresentadas na se=C3=A7=C3=A3o anterior usam a forma explicita, onde a = - palavra chave "join" =C3=A9 explicitamente usada na clausula "from".= Essa =C3=A9 a forma recomendada. - - - - A forma impl=C3=ADcita n=C3=A3o usa a palavra cha= ve "join". Entretanto, as associa=C3=A7=C3=B5es = - s=C3=A3o diferenciadas usando pontua=C3=A7=C3=A3o ("." - dotnation).= Uni=C3=B5es impl=C3=ADcitas podem aparecer em - qualquer das clausulas HQL. A uni=C3=A3o impl=C3=ADcita resulta em declara=C3=A7=C3=B5es - SQL que contem inner joins. = - - - - - - - Clausula select - - - A clausula select seleciona quais obetos e = propriedades retornam - no resultado da query. Considere: = - - - - - - A query selecionar=C3=A1 mates (companheiro= s), de outros Cats. = - Atualmente, podemos expressar a query de forma mais compacta c= omo: - - - - - - Queries podem retornar propriedades de qualquer tipo de valor,= incluindo propriedades de tipo de componente: - - - - - - - - - Queries podem retornar m=C3=BAltiplos objetos e/ou propriedade= s como um array do = - tipo Object[], - - - - = - - ou como um List, - - = - - = - - ou como um objeto Java typesafe, - - = - - = - - assumindo que a classe Family tenha um cons= trutor apropriado. - - = - - Pode-se designar referencias a express=C3=B5es selecionadas, <= literal>as: - - - - - - Isto =C3=A9 bem mais =C3=BAtil quando usado junto com= select new map: - - = - - - - Esta query retorna um Map de referencias pa= ra valores selecionados. - - = - - - - Fun=C3=A7=C3=B5es de agrega=C3=A7=C3=A3o - - - As queries HQL podem retornar o resultado de fun=C3=A7=C3=B5es= agregadas nas propriedades. - - - - - - - - As fun=C3=A7=C3=B5es agregadas suportadas s=C3=A3o: - - - - - - avg(...), sum(...), min(...), max(...) - - - - - count(*) - - - - - count(...), count(distinct ...), count(all...= ) - - - - = - - Pode-se usar operadores aritim=C3=A9ticos, concatena=C3=A7=C3= =A3o e fun=C3=A7=C3=B5es SQL = - reconhecidas na clausula select: - - = - - = - - = - - As palavras distinct e all podem ser usadas e t=C3=AAm = - a mesma sem=C3=A2ntica como no SQL. - - - - - - = - - Queries polim=C3=B3rficas - - - A query: - - - - - - retorna instancias n=C3=A3o s=C3=B3 de Cat,= mas tamb=C3=A9m de subclasses como = - DomesticCat. As queries do Hibernate podem = nomear qualquer classe Java = - ou interface na clausula from. A query reto= rnar=C3=A1 instancias de toda classe = - persistente que extenda a determinada classe ou implemente a = determinada interface. A query - , a seguir, pode retornar todo objeto persistente: = - - = - - = - - A interface Named pode ser implementada por= v=C3=A1rias classes persistentes: - - = - - = - - Note que as duas =C3=BAltimas queries requerem mais de um SQL = SELECT . Isto significa que a clausula = - order by n=C3=A3o ordena corretamente todo = o resultado. (Isso tamb=C3=A9m significa que = - voc=C3=AA n=C3=A3o pode chamar essas queries usando Q= uery.scroll().) = - - = - - - - A clausula where - - - A clausula where permite estreitar a lista = de instancias retornada. = - Se n=C3=A3o houver referencia alguma, pode-se referir a propri= edades pelo nome: - - - - = - - Se houver uma refer=C3=AAncia, use o nome da propriedade qualific= ada: = - - = - - - - retorna instancias de Cat com nome =E2=80= =98Fritz=E2=80=99. - - - - - - retornar=C3=A1 todas as instancias de Foo, = para cada = - um que tiver uma instancia de bar com a pro= priedade = - date igual a propriedade = - startDate de = - Foo. Express=C3=B5es de filtro compostas fa= zem da = - clausula where, extremamente poderosa. Cons= ideremos: - - - - - - Esta query traduzida para uma query SQL com= uma tabela (inner) join. Se fosse = - escrever algo como: - - - - - - Poderia-se terminar com uma query que neces= sitasse de join de quatro tabelas, = - no SQL. - - - - O operador =3D pode ser uasdo para comparar= n=C3=A3o apenas propriedades, = - mas tamb=C3=A9m instancias: = - - - - - - - - A propriedade especial (lowercase) id pode= ser usada para referenciar = - o identificador =C3=BAnico de um objeto. (Pode-se usar tamb=C3= =A9m o nome de sua propriedade) - - - - - - A Segunda query =C3=A9 eficiente. Nenhuma uni=C3=A3o de tabela= s =C3=A9 necess=C3=A1ria! - - - - As propriedades de identificadores compostas tamb=C3=A9m podem= ser usadas. Suponha que = - Person tenha um identificador composto que= consiste de = - country e medicareNumber. - - - - - - - - Mais uma vez, a Segunda query n=C3=A3o precisa de nenhum join = de tabela. - - = - - Assim mesmo, a propriedade especial class a= cessa o valor discriminador da = - instancia, no caso de persist=C3=AAncia polim=C3=B3rfica. O no= me de uma classe Java inclusa em uma = - clausula "where", ser=C3=A1 traduzida para seu valor descrimin= ante. = - - - - = - - Pode-se tamb=C3=A9m especificar as propriedades dos components= ou tipos de usu=C3=A1rio composto = - (e de componentes de componentes). Nunca tente usar uma expres= s=C3=A3o de filtro que termine na propriedade = - de um tipo de componente (ao contr=C3=A1rio de uma propriedade= de um componente). Por exemplo, = - se store.owner =C3=A9 uma entidade com um = componente address. - - - - - - Um tipo "any" tem as propriedades id e class especiais, = - n=C3=B4s permitindo expressar um join da seguinte forma (onde = AuditLog.item =C3=A9 = - uma propriedade mapeada com <an= y>) - - = - - = - - Veja que log.item.class e payment.= class podem = - referir-se a valores de colunas de banco de dados completament= e diferentes, na query acima. - - = - - - - Express=C3=B5es - - - As express=C3=B5es permitidas na cl=C3=A1usula where<= /literal> inclui a maioria = - das coisas que voc=C3=AA poderia escrever no SQL: - - - - - - operadores matem=C3=A1ticos +, -, *, / - - - - - operadores de compara=C3=A7=C3=A3o bin=C3=A1rios =3D, >=3D, <=3D, <>, !=3D, like - - - - - operadores l=C3=B3gicos and, or, not - - - - - parenteses ( ), indicating grouping - - - - - in, - not in, - between, - is null, - is not null, - is empty, - is not empty, - member of and = - not member of - - - - - case "simples" , case ... when ... then ... else= ... end, and - "searched" case, case when ... then ... else = ... end = - - - - - concatena=C3=A7=C3=A3o de string ...||... ou concat(...,...) - - - - - current_date(), current_ti= me(), - current_timestamp() - - - - - second(...), minute(...), = - hour(...), day(...), = - month(...), year(...), - - - - - qualquer funcao ou operador definida pela EJB-QL 3.0: = substring(), trim(), - lower(), upper(), length(), locate(), abs(), sqrt(), b= it_length(), mod() - - - - - coalesce() and nullif() - - - - - str() para converter valores numeri= cos ou temporais para string - - - - - cast(... as ...), onde o segundo ar= gumento =C3=A9 o nome do tipo = - hibernate, eextract(... from ...) s= e ANSI = - cast() e extract() =C3=A9 suportado pele - banco de dados usado - - - - - A fun=C3=A7=C3=A3o HQL index() , qu= e se aplicam a referencias de = - cole=C3=A7=C3=B4es associadas e indexadas - - - - - As fun=C3=A7=C3=B5es hql que retornam express=C3=B5es = de cole=C3=A7=C3=B5es de valores: - size(), minelement(), maxelement(), minindex(= ), maxindex(), = - junto com o elemento especial, elements(), - e fun=C3=A7=C3=B5es de =C3=ADndice = que podem ser quantificadas usando = - some, all, exists, any, in. = = - - - - - Qualquer fun=C3=A7=C3=A2o escalar pelo bando de dados = como sign(), = - trunc(), rtrim()= , sin() = - - - - - Parametros posicionais ao estilo JDBC ? - - - - - Parametros nomeados :name, :start_date, :x1 - - - - - Literais SQL 'foo', 69, 6.66E+2, - '1970-01-01 10:00:01.0' - - - - - Constantes Java public static final= ex: Color.TABBY - - - - - - in e between podem ser u= sadas da seguinte maneira: - - - - - - - - e as formas negativas podem ser escritas - - - - - - - - Likewise, is null and is not null<= /literal> may be used to test = - for null values. - Assim mesmo, , is null e is not nu= ll podem ser usados = - para testar valores nulos. - - - - Booleanos podem ser facilmente usados em express=C3=B5es, decl= arando as substitui=C3=A7=C3=B5es da HQL query, = - na configura=C3=A7=C3=A3o do Hibernate - - - true 1, false 0]]> - - - Isso ir=C3=A1 substituir as palavras chave true e false - pelos literais 1 e 0 na tradu=C3=A7=C3=A3o do HQL para SQL. - - - <= /programlisting> - - - Pode-se testar o tamanho de uma cole=C3=A7=C3=A3o com= a propriedade especial size, = - ou a fun=C3=A7=C3=A3o especial size(). - - - 0]]= > - - 0]= ]> - - - Para cole=C3=A7=C3=B5es indexadas, voc=C3=AA pode se referir a= os =C3=ADndices m=C3=A1ximo e m=C3=ADnimo, usando = - as fun=C3=A7=C3=B5es minindex e ma= xindex. Similarmente, = - pode-se referir aos elementos m=C3=A1ximo e m=C3=ADnimo de uma= cole=C3=A7=C3=A3o de tipos b=C3=A1sicos usando - as fun=C3=A7=C3=B5es minelement e = maxelement. - - = - current_date]]> - = - 100]]> - - 10000]]> - = - - As fun=C3=A7=C3=B5es SQL any, some, all, exists, in<= /literal> s=C3=A3o suportadas quando passado o = - elemento ou o conjunto de =C3=ADndices de uma cole=C3=A7=C3=A3= o (elements e = - indices de fun=C3=A7=C3=B5es), ou o resulta= do de uma subquery (veja abaixo). - - - - - - - - - all elements(p.sc= ores)]]> - - - - - Note que essas constru=C3=A7=C3=B5es - size= , elements, - indices, minindex, maxindex, - minelement, maxelement= =E2=80=93 = - s=C3=B3 podem ser usados na clausula where do Hibernate3. - - = - - Elementos de cole=C3=A7=C3=B5es com =C3=ADndice (arrays, lists= , maps), podem ser referenciadas = - pelo =C3=ADndice (apenas na clausula where): - - = - - - - - - - = - - - A express=C3=A3o entre colchetes [], pode s= er at=C3=A9 uma express=C3=A3o aritim=C3=A9tica. - - = - - = - - O HQL tamb=C3=A9m prov=C3=AA a fun=C3=A7=C3=A3o interna index(), para elementos de = - associa=C3=A7=C3=A3o um-pra-muitos ou cole=C3=A7=C3=A3o de val= ores. - - - - - - Fun=C3=A7=C3=B5es escalares SQL, suportadas pelo banco de dado= s subjacente. - - - - - - Se ainda ainda n=C3=A3o est=C3=A1 totalmente convencido, pense= o qu=C3=A3o maior e menos leg=C3=ADvel poderia = - ser a query a seguir, em SQL: - - - - - - Hint: something like - - - - - - - - A clausula order by - - - A lista retornada pela query pode ser ordenada por qualquer pr= opriedade da classe ou componente retornado: - - - - - - As op=C3=A7=C3=B5es asc ou desc indicam ordem crescente ou decrescente, = - respectivamente. = - - - - - A clausula group by - - - Uma query que retorne valores agregados, podem ser agrupados p= or qualquer propriedade de uma classe = - ou componente retornado: - - - - - - - - Uma clausula having tamb=C3=A9m =C3=A9 perm= itida. - - - - - - Fun=C3=A7=C3=B5es SQL e fun=C3=A7=C3=B5es agregadas s=C3=A3o p= ermitidas nas clausulas = - having e order by, se su= portadas pelo banco = - de dados subjacente (ex: n=C3=A3o no MySQL). = - - - 100 -order by count(kitten) asc, sum(kitten.weight) desc]]> - - - Note que, nem a clausula group by ou = - order by, podem conter express=C3=B5es arit= im=C3=A9ticas. - - - - = - - Subqueries - = - - Para bancos de dados que suportem subselects, o Hibernate supo= rta subqueries dentro de queries. = - Uma subquery precisa estar entre par=C3=AAnteses (normalmente = uma chamada de fun=C3=A7=C3=A3o agregada SQL). = - Mesmo subqueries co-relacionadas (subqueries que fazem refer= =C3=AAncia =C3=A0 alias de outras queries), = - s=C3=A3o aceitas. - - - ( = - select avg(cat.weight) from DomesticCat cat = -)]]> - - - = - - - - - - - - Note que HQL subqueries podem aparecer apenas dentro de clausu= las select ou where. - - - - Para subqueries com mais de uma express=C3= =A3o na lista do select, pode-se usar um construtor = - de tuplas: - - = - - - - Veja que em alguns bancos de dados (mas n=C3=A3o o Oracle ou H= SQL), pode-se usar construtores = - de tuplas em outros contextos. Por exemplo quando buscando com= ponentes ou tipos de usu=C3=A1rio composto. - - - - = - - Qual =C3=A9 equivalente ao mais verbalizado: - - = - - - - H=C3=A1 duas raz=C3=B5es boas que voc=C3=AA pode n=C3=A3o quer= er fazer este tipo de coisa: primeira, n=C3=A3o = - =C3=A9 completamente port=C3=A1vel entre plataformas de banco = de dados; segunda, a query agora =C3=A9 = - dependente da ordem de propriedades no documento de mapeamento. - - = - - - - Exemplos de HQL - = - - As queries do Hibernate, podem ser muito poderosas e complexas= . De fato, o poder da linguagem de = - querie =C3=A9 um dos pontos principais na distribui=C3=A7=C3= =A3o do Hibernate. Aqui temos algumas queries de exemplo, = - muito similares a queries que usei em um projeto recente. Note= que a maioria das queries que voc=C3=AA = - ir=C3=A1 escrever, s=C3=A3o mais simples que estas. - - = - - A query a seguir retorna o id de order, numero de itens e o va= lor total do order para todos os = - orders n=C3=A3o pagos para um fregu=C3=AAs particular e valor = total m=C3=ADnimo dado, ordenando os resultados por = - valor total. Ao determinar os pre=C3=A7os, =C3=A9 usado o cata= logo corrente. A query SQL resultante, = - usando tabelas ORDER, ORDER_LINE<= /literal>, PRODUCT, - CATALOG e PRICE, tem qua= tro inner joins e um = - (n=C3=A3o correlacionado) subselect. - - = - =3D all ( - select cat.effectiveDate = - from Catalog as cat - where cat.effectiveDate < sysdate - ) -group by order -having sum(price.amount) > :minAmount -order by sum(price.amount) desc]]> - = - - Que monstro! Atualmente, na vida real, eu n=C3=A3o sou muito a= fei=C3=A7oado a subqueries, ent=C3=A3o = - minha query seria mais parecida com isto: - - = - :minAmount -order by sum(price.amount) desc]]> - = - - A pr=C3=B3xima query conta o n=C3=BAmero de pagamentos em cada= status, tirando todos os pagamentos com = - status AWAITING_APPROVAL, onde a mais recen= te mudan=C3=A7a de status foi feita = - pelo usu=C3=A1rio corrente. Traduz-se para uma query SQL com dois inner joins e = - um subselect correlacionado, nas tabelas PAYMENT, = - PAYMENT_STATUS e PAYMENT_STATUS_CH= ANGE . - - - PaymentStatus.AWAITING_APPROVAL - or ( - statusChange.timeStamp =3D ( = - select max(change.timeStamp) = - from PaymentStatusChange change = - where change.payment =3D payment - ) - and statusChange.user <> :currentUser - ) -group by status.name, status.sortOrder -order by status.sortOrder]]> - - - Se eu tivesse mapeado a Collection statusChanges como um List, ao inv=C3=A9s de um = - Set, a query teria sido muito mais simples de escrever. - - = - PaymentStatus.AWAITING_APPROVAL - or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :c= urrentUser -group by status.name, status.sortOrder -order by status.sortOrder]]> - - - A pr=C3=B3xima query usa a fun=C3=A7=C3=A3o isNull()<= /literal> do MS SQL Server, para retornar = - todas as contas e pagamentos n=C3=A3o pagos para a organiza=C3= =A7=C3=A3o, para cada usu=C3=A1rio corrente = - pertencente. Traduz-se para uma query SQL com tr=C3=AAs inner joins, = - um outer join e um subselect nas tabelas ACCOUNT, PAYMENT, = - PAYMENT_STATUS,ACCOUNT_TYPE, = - ORGANIZATION e ORG_USER . - - - = - - - Para alguns bancos de dados, precisaremos eleminar o subselect= (correlacionado). - - - = - - - - - update e delete em lote - - - Agora o HQL suporta declara=C3=A7=C3=B5es, update, = - delete e insert ... select ... = - Veja , para mais detalhes. - - - - - Dicas e Truques - - - Pode-se contar o n=C3=BAmero de resultados da query, sem realm= ente retorna-los. - - - - - - Para ordenar um resultado pelo tamanho de uma Collection, use = a query a seguir. - - - - - - Se seu banco de dados suporta subselects, pode-se colocar uma = condi=C3=A7=C3=A3o sobre = - tamanho de sele=C3=A7=C3=A3o na cl=C3=A1usula where da sua que= ry: - - - = =3D 1]]> - - - Se seu banco de dados n=C3=A3o suporta subselects, use a query= a seguir: - - - =3D 1]]> - - - Com essa solu=C3=A7=C3=A3o n=C3=A3o se pode retornar um User com sem - nenhuma menssagem, por causa do "inner join", a forma a seguir= tamb=C3=A9m =C3=A9 =C3=BAtil. = - - - - - - As propriedades de um JavaBean podem ser limitadas =C3=A0 par= =C3=A2metros nomeados da query: - - - - - - As Collections s=C3=A3o paginaveis, usando a interface Query com um filtro: - - - - - - Os elementos da Collection podem ser ordenados ou agrupados = - usando um filtro de query: - - = - - - - Pode-se achar o tamanho de uma Collection sem inicializa-la: - - - - - - - - + + HQL: A linguagem de Queries do Hibernate + = + + O Hibernate vem com uma poderosa linguagem que =C3=A9 (intencional= mente) muito parecida = + com o SQL. Mas n=C3=A3o seja enganado pela sintaxe; a HQL =C3=A9 t= otalmente orientada =C3=A0 objetos, = + requer conhecimentos de heran=C3=A7a, polimorfismo e associa=C3=A7= =C3=B5es. = + + + + Case Sensit=C3=ADve + + + As Queries n=C3=A3o s=C3=A3o case-sensitive, exceto pelo nomes= das classes e propriedades Java. = + sELEct e o mesmo que = + SELECT mas + org.hibernate.eg.FOO n=C3=A3o =C3=A9 + org.hibernate.eg.Foo e + foo.barSet n=C3=A3o =C3=A9 + foo.BARSET. + = + + = + + Esse manual usa as palavras chave HQL em letras min=C3=BAscula= s. Alguns usu=C3=A1rios acham que = + com letras mai=C3=BAsculas as queries ficam mais leg=C3=ADveis= , mas n=C3=B3s achamos essa conven=C3=A7=C3=A3o feia = + dentro do c=C3=B3digo Java. + + = + + + + A clausula from + + + A mais simples query poss=C3=ADvel do Hibernate =C3=A9 a assim: + + = + + = + + Ela ir=C3=A1 retornar todas as instancias da classe e= g.Cat. + Necessariamente n=C3=A3o precisamos qualificar o nome da class= e, pois =C3=A9 realizado = + auto-import por padr=C3=A3o. Por isso na ma= ior parte do tempos = + n=C3=B3s simplesmente escrevemos: + + = + + = + + Na maior parte do tempo, voc=C3=AA precisar=C3=A1 atribuir um = alias, = + desde que voc=C3=AA queira se referia ao Cat em outras partes da = + query. + + + + + + Essa query atribui um alias a cat para as i= nstancias de = + Cat, ent=C3=A3o n=C3=B3s podemos usar esse = alias depois na query. = + A palavra chave as =C3=A9 opcional; poder=C3=ADamos escrever a= ssim: + + = + + = + + M=C3=BAltiplas classes pode ser envolvidas, resultando em um p= roduto cartesiano ou "cross" join. + + = + + + = + + =C3=89 considerada uma boa pr=C3=A1tica os nomes dos aliases c= ome=C3=A7arem com letra min=C3=BAscula, = + aderente com os padr=C3=B5es Java para vari=C3=A1veis locais (= ex: domesticCat). + + = + + + + Associa=C3=A7=C3=B5es e joins + + + N=C3=B3s tamb=C3=A9m podemos querer atribuir aliases em uma en= tidade associada, ou mesmo = + em elementos de uma cole=C3=A7=C3=A3o de valores, usando um join. + + + + + + + + + + Os tipos de joins suportados foram inspirados no SQL ANSI: + + + + + + inner join + + + + + left outer join + + + + + right outer join + + + + + full join (geralmente n=C3=A3o =C3= =A9 =C3=BAtil) + + + + = + + The inner join, left outer join and = + right outer join constructs may be abbrevia= ted. + As constru=C3=A7=C3=B5es inner join, left outer join e + right outer join podem ser abreviadas. = = + + + + = + + Voc=C3=AA pode fornecer condi=C3=A7=C3=B5es extras de join usa= ndo a palavra = + chave do HQL with. + + + with kitten.bodyWeight > 10.0]]> + + + Adicionalmente, um "fetch" join permite que associa=C3=A7=C3= =B5es ou cole=C3=A7=C3=B5es de valores = + sejam inicializadas junto com o objeto pai, usando apenas um s= elect. Isso =C3=A9 = + muito =C3=BAtil no caso das cole=C3=A7=C3=B5es. Isso efetivame= nte sobre escreve as declara=C3=A7=C3=B5es + outer join e lazy do arquivo mapeamento para associa=C3=A7=C3= =B5es e cole=C3=A7=C3=B5es. + Veja a se=C3=A7=C3=A3o para mais informa=C3=A7=C3=B5es. + + = + fetchcat.mate + left join fetchcat.kittens]]> + = + + Usualmente, um fetchjoin n=C3=A3o precisa a= tribuir um alias, pois o objeto associado n=C3=A3o = + deve ser usado na clausula where (ou em qua= lquer outra clausula). = + Tamb=C3=A9m, os objetos associados n=C3=A3o s=C3=A3o retornado= s diretamente nos resultados da query. = + Ao inv=C3=A9s disso, eles devem ser acessados usando o objeto = pai. A =C3=BAnica raz=C3=A3o que n=C3=B3s = + podemos necessitar de um alias =C3=A9 quando fazemos um fech j= oin recursivamente em uma = + cole=C3=A7=C3=A3o adicional: + + = + fetchcat.mate + left join fetchcat.kittens child + left join fetchchild.kittens]]> + = + + Observe que a constru=C3=A7=C3=A3o fetch n= =C3=A3o deve ser usada em queries invocadas usando = + iterate() (embora possa ser usado com scroll()). O = + fetch tamb=C3=A9m n=C3=A3o deve ser usado j= unto com o setMaxResults() ou = + setFirstResult() pois essas opera=C3=A7=C3= =B5es s=C3=A3o baseadas nas linhas retornadas, que = + normalmente contem duplicidade devido ao fetching das cole=C3= =A7=C3=B5es, ent=C3=A3o o n=C3=BAmero de linhas pode n=C3=A3o = + ser o que voc=C3=AA espera. = + = + O fetch n=C3=A3o deve ser usado junto com u= ma condi=C3=A7=C3=A3o with em = + uma condi=C3=A7=C3=A3o with ad hoc. =C3=89 = poss=C3=ADvel que seja criado um produto cartesiano pelo = + join fetching em mais do que uma cole=C3=A7=C3=A3o em uma quer= y, ent=C3=A3o tome cuidado nesses casos. Um join = + fetching em varias cole=C3=A7=C3=B5es pode trazer resultados i= nesperados para mapeamentos do tipo bag, tome = + cuidado na hora de formular queries como essas. Finalmente, ob= serve o seguinte, o = + full join fetch e right join fetch= n=C3=A3o s=C3=A3o significativos. + + = + + = + Se est=C3=A1 usando o n=C3=ADvel de propriedade lazy (com instrumenta=C3=A7=C3=A3o de bytecode), =C3=A9 poss=C3=ADvel = + for=C3=A7ar o Hibernate a buscar as propri= edades lazy imediatamente (na primeira query), = + usando fetch all properties . = + + = + fetchall= properties order by name]]> + fetchall properties where lower(doc.name) like '%cats%']]> + + + + + Formas e sintaxe de joins + + + O HQL suporta duas formas de associa=C3=A7=C3=A3o para uni=C3=A3o: <= literal>impl=C3=ADcita e explicita. + + + + As queries apresentadas na se=C3=A7=C3=A3o anterior usam a forma explicita, onde a = + palavra chave "join" =C3=A9 explicitamente usada na clausula "from".= Essa =C3=A9 a forma recomendada. + + + + A forma impl=C3=ADcita n=C3=A3o usa a palavra cha= ve "join". Entretanto, as associa=C3=A7=C3=B5es = + s=C3=A3o diferenciadas usando pontua=C3=A7=C3=A3o ("." - dotnation).= Uni=C3=B5es impl=C3=ADcitas podem aparecer em + qualquer das clausulas HQL. A uni=C3=A3o impl=C3=ADcita resulta em declara=C3=A7=C3=B5es + SQL que contem inner joins. = + + + + + + + Refering to identifier property + = + + There are, generally speaking, 2 ways to refer to an entity's identifie= r property: + + + + + The special property (lowercase) id may be used to= reference the identifier + property of an entity provided that entity does not define = a non-identifier property + named id. + + + + + If the entity defines a named identifier property, you may use that p= roperty name. + + + + = + + References to composite identifier properties follow the same naming ru= les. If the + entity has a non-identifier property named id, the composite identifier= property can only + be referenced by its defined named; otherwise, the special id<= /literal> property + can be used to rerference the identifier property. + + = + + Note: this has changed significantly starting in version 3.2.2. In pre= vious versions, + id always referred to the ident= ifier property no + matter what its actual name. A ramification of that decision was that = non-identifier + properties named id could never be referenced in Hib= ernate queries. + + + + + Clausula select + + + A clausula select seleciona quais obetos e = propriedades retornam + no resultado da query. Considere: = + + + + + + A query selecionar=C3=A1 mates (companheiro= s), de outros Cats. = + Atualmente, podemos expressar a query de forma mais compacta c= omo: + + + + + + Queries podem retornar propriedades de qualquer tipo de valor,= incluindo propriedades de tipo de componente: + + + + + + + + + Queries podem retornar m=C3=BAltiplos objetos e/ou propriedade= s como um array do = + tipo Object[], + + + + = + + ou como um List, + + = + + = + + ou como um objeto Java typesafe, + + = + + = + + assumindo que a classe Family tenha um cons= trutor apropriado. + + = + + Pode-se designar referencias a express=C3=B5es selecionadas, <= literal>as: + + + + + + Isto =C3=A9 bem mais =C3=BAtil quando usado junto com= select new map: + + = + + + + Esta query retorna um Map de referencias pa= ra valores selecionados. + + = + + + + Fun=C3=A7=C3=B5es de agrega=C3=A7=C3=A3o + + + As queries HQL podem retornar o resultado de fun=C3=A7=C3=B5es= agregadas nas propriedades. + + + + + + + + As fun=C3=A7=C3=B5es agregadas suportadas s=C3=A3o: + + + + + + avg(...), sum(...), min(...), max(...) + + + + + count(*) + + + + + count(...), count(distinct ...), count(all...= ) + + + + = + + Pode-se usar operadores aritim=C3=A9ticos, concatena=C3=A7=C3= =A3o e fun=C3=A7=C3=B5es SQL = + reconhecidas na clausula select: + + = + + = + + = + + As palavras distinct e all podem ser usadas e t=C3=AAm = + a mesma sem=C3=A2ntica como no SQL. + + + + + + = + + Queries polim=C3=B3rficas + + + A query: + + + + + + retorna instancias n=C3=A3o s=C3=B3 de Cat,= mas tamb=C3=A9m de subclasses como = + DomesticCat. As queries do Hibernate podem = nomear qualquer classe Java = + ou interface na clausula from. A query reto= rnar=C3=A1 instancias de toda classe = + persistente que extenda a determinada classe ou implemente a = determinada interface. A query + , a seguir, pode retornar todo objeto persistente: = + + = + + = + + A interface Named pode ser implementada por= v=C3=A1rias classes persistentes: + + = + + = + + Note que as duas =C3=BAltimas queries requerem mais de um SQL = SELECT . Isto significa que a clausula = + order by n=C3=A3o ordena corretamente todo = o resultado. (Isso tamb=C3=A9m significa que = + voc=C3=AA n=C3=A3o pode chamar essas queries usando Q= uery.scroll().) = + + = + + + + A clausula where + + + A clausula where permite estreitar a lista = de instancias retornada. = + Se n=C3=A3o houver referencia alguma, pode-se referir a propri= edades pelo nome: + + + + = + + Se houver uma refer=C3=AAncia, use o nome da propriedade qualific= ada: = + + = + + + + retorna instancias de Cat com nome =E2=80= =98Fritz=E2=80=99. + + + + + + retornar=C3=A1 todas as instancias de Foo, = para cada = + um que tiver uma instancia de bar com a pro= priedade = + date igual a propriedade = + startDate de = + Foo. Express=C3=B5es de filtro compostas fa= zem da = + clausula where, extremamente poderosa. Cons= ideremos: + + + + + + Esta query traduzida para uma query SQL com= uma tabela (inner) join. Se fosse = + escrever algo como: + + + + + + Poderia-se terminar com uma query que neces= sitasse de join de quatro tabelas, = + no SQL. + + + + O operador =3D pode ser uasdo para comparar= n=C3=A3o apenas propriedades, = + mas tamb=C3=A9m instancias: = + + + + + + + + A propriedade especial (lowercase) id pode= ser usada para referenciar = + o identificador =C3=BAnico de um objeto. (Pode-se usar tamb=C3= =A9m o nome de sua propriedade) + + + + + + A Segunda query =C3=A9 eficiente. Nenhuma uni=C3=A3o de tabela= s =C3=A9 necess=C3=A1ria! + + + + As propriedades de identificadores compostas tamb=C3=A9m podem= ser usadas. Suponha que = + Person tenha um identificador composto que= consiste de = + country e medicareNumber. + + + + + + + + Mais uma vez, a Segunda query n=C3=A3o precisa de nenhum join = de tabela. + + = + + Assim mesmo, a propriedade especial class a= cessa o valor discriminador da = + instancia, no caso de persist=C3=AAncia polim=C3=B3rfica. O no= me de uma classe Java inclusa em uma = + clausula "where", ser=C3=A1 traduzida para seu valor descrimin= ante. = + + + + = + + Pode-se tamb=C3=A9m especificar as propriedades dos components= ou tipos de usu=C3=A1rio composto = + (e de componentes de componentes). Nunca tente usar uma expres= s=C3=A3o de filtro que termine na propriedade = + de um tipo de componente (ao contr=C3=A1rio de uma propriedade= de um componente). Por exemplo, = + se store.owner =C3=A9 uma entidade com um = componente address. + + + + + + Um tipo "any" tem as propriedades id e class especiais, = + n=C3=B4s permitindo expressar um join da seguinte forma (onde = AuditLog.item =C3=A9 = + uma propriedade mapeada com <an= y>) + + = + + = + + Veja que log.item.class e payment.= class podem = + referir-se a valores de colunas de banco de dados completament= e diferentes, na query acima. + + = + + + + Express=C3=B5es + + + As express=C3=B5es permitidas na cl=C3=A1usula where<= /literal> inclui a maioria = + das coisas que voc=C3=AA poderia escrever no SQL: + + + + + + operadores matem=C3=A1ticos +, -, *, / + + + + + operadores de compara=C3=A7=C3=A3o bin=C3=A1rios =3D, >=3D, <=3D, <>, !=3D, like + + + + + operadores l=C3=B3gicos and, or, not + + + + + parenteses ( ), indicating grouping + + + + + in, + not in, + between, + is null, + is not null, + is empty, + is not empty, + member of and = + not member of + + + + + case "simples" , case ... when ... then ... else= ... end, and + "searched" case, case when ... then ... else = ... end = + + + + + concatena=C3=A7=C3=A3o de string ...||... ou concat(...,...) + + + + + current_date(), current_ti= me(), + current_timestamp() + + + + + second(...), minute(...), = + hour(...), day(...), = + month(...), year(...), + + + + + qualquer funcao ou operador definida pela EJB-QL 3.0: = substring(), trim(), + lower(), upper(), length(), locate(), abs(), sqrt(), b= it_length(), mod() + + + + + coalesce() and nullif() + + + + + str() para converter valores numeri= cos ou temporais para string + + + + + cast(... as ...), onde o segundo ar= gumento =C3=A9 o nome do tipo = + hibernate, eextract(... from ...) s= e ANSI = + cast() e extract() =C3=A9 suportado pele + banco de dados usado + + + + + A fun=C3=A7=C3=A3o HQL index() , qu= e se aplicam a referencias de = + cole=C3=A7=C3=B4es associadas e indexadas + + + + + As fun=C3=A7=C3=B5es hql que retornam express=C3=B5es = de cole=C3=A7=C3=B5es de valores: + size(), minelement(), maxelement(), minindex(= ), maxindex(), = + junto com o elemento especial, elements(), + e fun=C3=A7=C3=B5es de =C3=ADndice = que podem ser quantificadas usando = + some, all, exists, any, in. = = + + + + + Qualquer fun=C3=A7=C3=A2o escalar pelo bando de dados = como sign(), = + trunc(), rtrim()= , sin() = + + + + + Parametros posicionais ao estilo JDBC ? + + + + + Parametros nomeados :name, :start_date, :x1 + + + + + Literais SQL 'foo', 69, 6.66E+2, + '1970-01-01 10:00:01.0' + + + + + Constantes Java public static final= ex: Color.TABBY + + + + + + in e between podem ser u= sadas da seguinte maneira: + + + + + + + + e as formas negativas podem ser escritas + + + + + + + + Likewise, is null and is not null<= /literal> may be used to test = + for null values. + Assim mesmo, , is null e is not nu= ll podem ser usados = + para testar valores nulos. + + + + Booleanos podem ser facilmente usados em express=C3=B5es, decl= arando as substitui=C3=A7=C3=B5es da HQL query, = + na configura=C3=A7=C3=A3o do Hibernate + + + true 1, false 0]]> + + + Isso ir=C3=A1 substituir as palavras chave true e false + pelos literais 1 e 0 na tradu=C3=A7=C3=A3o do HQL para SQL. + + + <= /programlisting> + + + Pode-se testar o tamanho de uma cole=C3=A7=C3=A3o com= a propriedade especial size, = + ou a fun=C3=A7=C3=A3o especial size(). + + + 0]]= > + + 0]= ]> + + + Para cole=C3=A7=C3=B5es indexadas, voc=C3=AA pode se referir a= os =C3=ADndices m=C3=A1ximo e m=C3=ADnimo, usando = + as fun=C3=A7=C3=B5es minindex e ma= xindex. Similarmente, = + pode-se referir aos elementos m=C3=A1ximo e m=C3=ADnimo de uma= cole=C3=A7=C3=A3o de tipos b=C3=A1sicos usando + as fun=C3=A7=C3=B5es minelement e = maxelement. + + = + current_date]]> + = + 100]]> + + 10000]]> + = + + As fun=C3=A7=C3=B5es SQL any, some, all, exists, in<= /literal> s=C3=A3o suportadas quando passado o = + elemento ou o conjunto de =C3=ADndices de uma cole=C3=A7=C3=A3= o (elements e = + indices de fun=C3=A7=C3=B5es), ou o resulta= do de uma subquery (veja abaixo). + + + + + + + + + all elements(p.sc= ores)]]> + + + + + Note que essas constru=C3=A7=C3=B5es - size= , elements, + indices, minindex, maxindex, + minelement, maxelement= =E2=80=93 = + s=C3=B3 podem ser usados na clausula where do Hibernate3. + + = + + Elementos de cole=C3=A7=C3=B5es com =C3=ADndice (arrays, lists= , maps), podem ser referenciadas = + pelo =C3=ADndice (apenas na clausula where): + + = + + + + + + + = + + + A express=C3=A3o entre colchetes [], pode s= er at=C3=A9 uma express=C3=A3o aritim=C3=A9tica. + + = + + = + + O HQL tamb=C3=A9m prov=C3=AA a fun=C3=A7=C3=A3o interna index(), para elementos de = + associa=C3=A7=C3=A3o um-pra-muitos ou cole=C3=A7=C3=A3o de val= ores. + + + + + + Fun=C3=A7=C3=B5es escalares SQL, suportadas pelo banco de dado= s subjacente. + + + + + + Se ainda ainda n=C3=A3o est=C3=A1 totalmente convencido, pense= o qu=C3=A3o maior e menos leg=C3=ADvel poderia = + ser a query a seguir, em SQL: + + + + + + Hint: something like + + + + + + + + A clausula order by + + + A lista retornada pela query pode ser ordenada por qualquer pr= opriedade da classe ou componente retornado: + + + + + + As op=C3=A7=C3=B5es asc ou desc indicam ordem crescente ou decrescente, = + respectivamente. = + + + + + A clausula group by + + + Uma query que retorne valores agregados, podem ser agrupados p= or qualquer propriedade de uma classe = + ou componente retornado: + + + + + + + + Uma clausula having tamb=C3=A9m =C3=A9 perm= itida. + + + + + + Fun=C3=A7=C3=B5es SQL e fun=C3=A7=C3=B5es agregadas s=C3=A3o p= ermitidas nas clausulas = + having e order by, se su= portadas pelo banco = + de dados subjacente (ex: n=C3=A3o no MySQL). = + + + 100 +order by count(kitten) asc, sum(kitten.weight) desc]]> + + + Note que, nem a clausula group by ou = + order by, podem conter express=C3=B5es arit= im=C3=A9ticas. + + + + = + + Subqueries + = + + Para bancos de dados que suportem subselects, o Hibernate supo= rta subqueries dentro de queries. = + Uma subquery precisa estar entre par=C3=AAnteses (normalmente = uma chamada de fun=C3=A7=C3=A3o agregada SQL). = + Mesmo subqueries co-relacionadas (subqueries que fazem refer= =C3=AAncia =C3=A0 alias de outras queries), = + s=C3=A3o aceitas. + + + ( = + select avg(cat.weight) from DomesticCat cat = +)]]> + + + = + + + + + + + + Note que HQL subqueries podem aparecer apenas dentro de clausu= las select ou where. + + + + Note that subqueries can also utilize row value constructor syntax. See + for more details. + = + + + + Exemplos de HQL + = + + As queries do Hibernate, podem ser muito poderosas e complexas= . De fato, o poder da linguagem de = + querie =C3=A9 um dos pontos principais na distribui=C3=A7=C3= =A3o do Hibernate. Aqui temos algumas queries de exemplo, = + muito similares a queries que usei em um projeto recente. Note= que a maioria das queries que voc=C3=AA = + ir=C3=A1 escrever, s=C3=A3o mais simples que estas. + + = + + A query a seguir retorna o id de order, numero de itens e o va= lor total do order para todos os = + orders n=C3=A3o pagos para um fregu=C3=AAs particular e valor = total m=C3=ADnimo dado, ordenando os resultados por = + valor total. Ao determinar os pre=C3=A7os, =C3=A9 usado o cata= logo corrente. A query SQL resultante, = + usando tabelas ORDER, ORDER_LINE<= /literal>, PRODUCT, + CATALOG e PRICE, tem qua= tro inner joins e um = + (n=C3=A3o correlacionado) subselect. + + = + =3D all ( + select cat.effectiveDate = + from Catalog as cat + where cat.effectiveDate < sysdate + ) +group by order +having sum(price.amount) > :minAmount +order by sum(price.amount) desc]]> + = + + Que monstro! Atualmente, na vida real, eu n=C3=A3o sou muito a= fei=C3=A7oado a subqueries, ent=C3=A3o = + minha query seria mais parecida com isto: + + = + :minAmount +order by sum(price.amount) desc]]> + = + + A pr=C3=B3xima query conta o n=C3=BAmero de pagamentos em cada= status, tirando todos os pagamentos com = + status AWAITING_APPROVAL, onde a mais recen= te mudan=C3=A7a de status foi feita = + pelo usu=C3=A1rio corrente. Traduz-se para uma query SQL com dois inner joins e = + um subselect correlacionado, nas tabelas PAYMENT, = + PAYMENT_STATUS e PAYMENT_STATUS_CH= ANGE . + + + PaymentStatus.AWAITING_APPROVAL + or ( + statusChange.timeStamp =3D ( = + select max(change.timeStamp) = + from PaymentStatusChange change = + where change.payment =3D payment + ) + and statusChange.user <> :currentUser + ) +group by status.name, status.sortOrder +order by status.sortOrder]]> + + + Se eu tivesse mapeado a Collection statusChanges como um List, ao inv=C3=A9s de um = + Set, a query teria sido muito mais simples de escrever. + + = + PaymentStatus.AWAITING_APPROVAL + or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :c= urrentUser +group by status.name, status.sortOrder +order by status.sortOrder]]> + + + A pr=C3=B3xima query usa a fun=C3=A7=C3=A3o isNull()<= /literal> do MS SQL Server, para retornar = + todas as contas e pagamentos n=C3=A3o pagos para a organiza=C3= =A7=C3=A3o, para cada usu=C3=A1rio corrente = + pertencente. Traduz-se para uma query SQL com tr=C3=AAs inner joins, = + um outer join e um subselect nas tabelas ACCOUNT, PAYMENT, = + PAYMENT_STATUS,ACCOUNT_TYPE, = + ORGANIZATION e ORG_USER . + + + = + + + Para alguns bancos de dados, precisaremos eleminar o subselect= (correlacionado). + + + = + + + + + update e delete em lote + + + Agora o HQL suporta declara=C3=A7=C3=B5es, update, = + delete e insert ... select ... = + Veja , para mais detalhes. + + + + + Dicas e Truques + + + Pode-se contar o n=C3=BAmero de resultados da query, sem realm= ente retorna-los. + + + + + + Para ordenar um resultado pelo tamanho de uma Collection, use = a query a seguir. + + + + + + Se seu banco de dados suporta subselects, pode-se colocar uma = condi=C3=A7=C3=A3o sobre = + tamanho de sele=C3=A7=C3=A3o na cl=C3=A1usula where da sua que= ry: + + + = =3D 1]]> + + + Se seu banco de dados n=C3=A3o suporta subselects, use a query= a seguir: + + + =3D 1]]> + + + Com essa solu=C3=A7=C3=A3o n=C3=A3o se pode retornar um User com sem + nenhuma menssagem, por causa do "inner join", a forma a seguir= tamb=C3=A9m =C3=A9 =C3=BAtil. = + + + + + + As propriedades de um JavaBean podem ser limitadas =C3=A0 par= =C3=A2metros nomeados da query: + + + + + + As Collections s=C3=A3o paginaveis, usando a interface Query com um filtro: + + + + + + Os elementos da Collection podem ser ordenados ou agrupados = + usando um filtro de query: + + = + + + + Pode-se achar o tamanho de uma Collection sem inicializa-la: + + + + + + + + Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/qu= ery_sql.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sq= l.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/query_sq= l.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Native SQL = You may also express queries in the native SQL dialect of your Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/se= ssion_api.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_= api.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/session_= api.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,1248 +1,1270 @@ = -=EF=BB=BF=EF=BB=BF - Trabalhando com objetos - - - O Hibernate =C3=A9 uma solu=C3=A7=C3=A3o completa de mapeamento ob= jeto/relacional que n=C3=A3o apenas = - poupa o desenvolvedor dos detalhes de baixo n=C3=ADvel do sistema = de gerenciamento do = - banco de dados, mas tamb=C3=A9m oferece um gerenciamento= de estado - para objetos. Isto =C3=A9, ao contr=C3=A1rio do gerenciamento de = instru=C3=A7=C3=B5es - SQL em camadas de persist=C3=AAncia JDBC/SQL comuns, uma vis=C3=A3= o natural da persist=C3=AAncia = - orientada a objetos em aplica=C3=A7=C3=B5es Java. - - - - Em outras palavras, desenvolvedores de aplica=C3=A7=C3=B5es Hibern= ate podem sempre pensar em = - rela=C3=A7=C3=A3o ao estado de seus objetos, = e n=C3=A3o necessariamente em = - rela=C3=A7=C3=A3o a execu=C3=A7=C3=A3o de instru=C3=A7=C3=B5es SQL= . Este parte =C3=A9 responsabilidade do Hibernate e = - =C3=A9 relevante aos desenvolvedores de aplica=C3=A7=C3=B5es apena= s quando est=C3=A3o ajustando = - a performance do sistema. - - - - Estado dos objetos no Hibernate - - - O Hibernate define e suporta os seguintes estados de um objeto= s: - - - - - - Transient - um objeto =C3=A9 tran= siente se ele foi instanciando = - usando apenas o operador new, e n= =C3=A3o foi associado com uma = - Session do Hibernate. Ele n=C3=A3o = ter=C3=A1 uma representa=C3=A7=C3=A3o = - persistente no banco de dados e nenhum identificador s= er=C3=A1 atribu=C3=ADdo para ele. = - Inst=C3=A2ncias transientes ser=C3=A3o destru=C3=ADdas= pelo coletor de lixo se a aplica=C3=A7=C3=A3o = - n=C3=A3o manter sua refer=C3=AAncia. Use uma = Session do Hibernate = - para tornar o objeto persistente ( e deixe o Hibernate= gerenciar as = - instru=C3=A7=C3=B5es SQL que ser=C3=A3o necess=C3=A1ri= as para executar esta transi=C3=A7=C3=A3o). - - - - - Persistent -=E2=80=93 uma inst=C3= =A2ncia persistente possui uma = - representa=C3=A7=C3=A3o no banco de dados e um identif= icador. Ele pode ter sido salvo = - ou carregado, assim, ele est=C3=A1 por defini=C3=A7=C3= =A3o no escopo de uma = - Session. O Hibernate ir=C3=A1 detec= tar qualquer mudan=C3=A7a feita a = - um objeto persistente e sincronizar o seu estado com o= banco de dados quando = - completar a unidade de trabalho. Desenvolvedores n=C3= =A3o executam instru=C3=A7=C3=B5es manuais = - de UPDATE, ou instru=C3=A7=C3=B5es = de DELETE = - quando o objeto deve ser passado para transiente. - - - - - Detached =E2=80=93 uma inst=C3=A2= ncia desaclopada =C3=A9 um objeto que = - foi persistido, mas sua Session foi= fechada. A refer=C3=AAncia = - ao objeto continua v=C3=A1lida, =C3=A9 claro, e a ins= t=C3=A2ncia destacada desaclopada pode = - ser acoplada a uma nova Session no = futuro, fazendo-o = - ( e todas as modifica=C3=A7=C3=B5es sofridas) persiste= nte novamente. Essa caracter=C3=ADstica = - possibilita um modelo de programa=C3=A7=C3=A3o para un= idades de trabalho que rodam = - durante muito tempo que requer um pensamento por tempo= do usu=C3=A1rio. Podemos = - chamar-las de transa=C3=A7=C3=B5es da aplica= =C3=A7=C3=A3o, i.e. uma unidade = - de trabalho do ponto de vista do usu=C3=A1rio. - - - - - - Agora iremos discutir os estados e suas transi=C3=A7=C3=B5es (= e os m=C3=A9todos do Hibernate que = - disparam uma transi=C3=A7=C3=A3o) em mais detalhes. - - - - - - Tornando os objetos persistentes - - - Inst=C3=A2ncias recentemente instanciadas de uma classe persis= tente s=C3=A3o = - consideradas transientes pelo Hibernate. - Podemos tornar uma inst=C3=A2ncia transiente em per= sistente - associando-a a uma sess=C3=A3o: = - - - - - - Se Cat possui um identificador gerado, o id= entificador = - =C3=A9 gerado e atribu=C3=ADdo a cat quando= save() = - for chamada. Se Cat possuir um identificado= r = - Associado, ou uma chave composta, o identif= icador deve ser = - atribu=C3=ADdo =C3=A0 inst=C3=A2ncia de cat= antes que save() = - seja chamado. Pode-se usar tamb=C3=A9m persist() ao inv=C3=A9s de = - save(), com a sem=C3=A2ntica definada no n= ovo esbo=C3=A7o do EJB3. - - = - - Alternativamente, pode-se atribuir o identificador usando uma = vers=C3=A3o = - sobrecarregada de save(). - - - - = - - Se o objeto persistido possuir objetos associados (e.g. a cole= =C3=A7=C3=A3o = - kittens no exemplo anterior), esses objetos= podem ser = - tornar persistente em qualquer ordem que se queira ao menos qu= e se tenha uma = - restri=C3=A7=C3=A3o NOT NULL em uma coluna = de chave estrangeira. = - Nunca h=C3=A1 risco de viola=C3=A7=C3=A3o de restri=C3=A7=C3= =B5es de chave estrangeira. Assim, = - pode-se violar uma restri=C3=A7=C3=A3o NOT NULL se = - save() for usada nos objetos em uma ordem e= rrada. - - = - - Geralmente voc=C3=AA n=C3=A3o deve se importar com esses detal= hes, muito provavelmente se = - usar=C3=A1 a caracter=C3=ADstica de persist=C3=AAnci= a transitiva do Hibernate = - para salvar os objetos associados automaticamente. Ent=C3=A3o,= enquanto uma restri=C3=A7=C3=A3o = - NOT NULL n=C3=A3o ocorrer =E2=80=93 Hiberna= te tomar=C3=A1 conta de tudo. = - Persist=C3=AAncia transitiva ser=C3=A1 discutida futuramente n= esse cap=C3=ADtulo. - - = - - - - Carregando o objetos - - - O m=C3=A9todo load() de uma Sessi= on nos = - fornece um meio para recuperar uma inst=C3=A2ncia persistente = se o identificador = - for conhecido. load() recebe uma classe do = objeto e carregar=C3=A1 - o estado em uma inst=C3=A2ncia mais recente dessa classe, no e= stado persistente. = - - - - - - - - Alternatively, you can load state into a given instance: -Alternativamente, pode-se carregar um estado em uma inst=C3=A2ncia dada: - - - - - - Repare que load() ir=C3=A1 lan=C3=A7ar uma = exce=C3=A7=C3=A3o irrecuper=C3=A1vel = - se n=C3=A3o houver na tabela no banco de dados um registro que= combine. = - Se a classe for mapeada com um proxy, load() = - simplesmente retorna um proxy n=C3=A3o inicializado e realment= e n=C3=A3o chamar=C3=A1 = - o banco de dados at=C3=A9 que um m=C3=A9todo do proxy seja inv= ocado. = - Esse comportamento =C3=A9 muito =C3=BAtil se deseja-se criar u= ma associa=C3=A7=C3=A3o = - com um objeto sem que realmente o carregue do bando de dados. = - Isto tamb=C3=A9m permite que sejam carregadas m=C3=BAltiplas i= nst=C3=A2ncias como um = - grupo se batch-size estiver para o mapeamen= to da = - classe. - - = - - Se voc=C3=AA n=C3=A3o tiver certeza da existencia do registro = no banco, voc=C3=AA deve - usar o metodo get(), que consulta o banco = - imediantamente e retorna um null se n=C3=A3o existir o registr= o. - - = - - - - Tamb=C3=A9m pode-se carregar um objeto usando SELECT = ... FOR UPDATE, = - usando um LockMode. Veja a documenta=C3=A7= =C3=A3o da API para maiores = - informa=C3=A7=C3=B5es. - - - - = - - Note that any associated instances or contained collections ar= e = - not selected FOR UPDATE, unless you decide - to specify lock or all a= s a - cascade style for the association. - - = - - O recarregamento de um objeto e todas as suas cole=C3=A7=C3=B5= es =C3=A9 poss=C3=ADvel a qualquer momento, = - usando o m=C3=A9todo refresh(). Util quando= as triggers do banco de = - dados s=C3=A3o usados para inicializar algumas propriedades d= o objeto. - - = - - - - Uma importante quest=C3=A3o geralmente aparece neste ponto: O = quanto Hibernate carrega = - do banco de dados e quantos SQL SELECT ele= ir=C3=A1 usar? Isto = - depende da estrat=C3=A9gia de recupera=C3=A7=C3=A3o<= /emphasis>usada e explicada na = - . - - - - - - Consultando - - - Se o identificador do objeto que se est=C3=A1 buscando n=C3=A3= o for conhecido, = - uma consulta ser=C3=A1 necess=C3=A1ria. O Hibernate suporta um= a linguagem de consulta = - (HQL) orientada a objetos f=C3=A1cil mas poderosa. Para cria= =C3=A7=C3=A3o via programa=C3=A7=C3=A3o = - de consultas, o Hibernate suporta caracter=C3=ADsticas sofisti= cadas de consulta = - por Crit=C3=A9rio e Exemplo (QBCe QBE). Pode-se tamb=C3=A9m ex= pressar a consulta = - por meio de SQL nativa do banco de dados, com suporte opcional= do Hibernate = - para convers=C3=A3o do conjunto de reultados em objetos. - - - - Executando consultas - - - Consultas HQL e SQL nativa s=C3=A3o representadas por uma = inst=C3=A2ncia de org.hibernate.Query. - Esta interface oferece m=C3=A9todos para associa=C3=A7=C3= =A3o de par=C3=A2metros, tratamento de conjunto de resultados, = - e para a execu=C3=A7=C3=A3o de consultas reais. Voc=C3=AA = pode obter uma Query usando a = - Session atual: - - - - - - Geralmente uma consulta =C3=A9 executada ao invocar list(), = - o resultado da consulta ser=C3=A1 carregado completamente = em uma cole=C3=A7=C3=A3o na mem=C3=B3ria. = - Inst=C3=A2ncias de entidades recuperadas por uma consulta = est=C3=A3o no estado persistente. = - O uniqueResult() oferece um atalho se v= oc=C3=AA souber de = - previamente que a consulta retornar=C3=A1 apenas um =C3=BA= nico objeto. Repare que consultas = - que fazem uso de buscas de cole=C3=A7=C3=B5es de forma ans= iosa (eager) geralmente retornam = - duplicatas dos objetos raiz ( mas com suas cole=C3=A7=C3= =B5es inicializadas ). Pode-se = - filtrar estas duplicatas atrav=C3=A9s de um simples Set. - - - - Interagindo com resultados - - - Ocasionalmente, deves-se ser capaz de atingir performa= nces melhores com = - a execu=C3=A7=C3=A3o de consultas usando o m=C3=A9todo= iterate(). = - Geralmente isso ser=C3=A1 o caso esperado apenas se as= inst=C3=A2ncias dos entidades = - reais retornadas pela consulta j=C3=A1 estiverem na se= ss=C3=A3o ou no cach=C3=A9 de segundo = - n=C3=ADvel. Caso elas ainda n=C3=A3o tenham sido armaz= enadas, iterate() = - ser=C3=A1 mais devagar do que list() e pode ser necess=C3=A1rio v=C3=A1rios = - acessos ao banco de dados para um simples consulta, ge= ralmente 1 - para a sele=C3=A7=C3=A3o inicial que retorna apenas id= entificadores, e n - consultas adicionais para inicializar as inst=C3=A2nci= as reais. - - - - - = - - Consultas que retornam tuplas - - - Algumas vezes as consultas do Hibernate retornam tupla= s de objetos, nesse caso = - cada tupla =C3=A9 retornada como um array: = = - - - - - - - - Resultados escalares - - - Consultas devem especificar uma propriedade da classe = na clausula = - select. Elas tamb=C3=A9m podem cham= ar fun=C3=A7=C3=B5es SQL de agrega=C3=A7=C3=A3os. = - Propriedades ou agrega=C3=A7=C3=B5es s=C3=A3o consider= ados resultados agregados = - ( e n=C3=A3o entidades no estado persistente). - - - - - - - - Bind parameters - - - Methods on Query are provided for b= inding values to - named parameters or JDBC-style ? pa= rameters. = - Contrary to JDBC, Hibernate numbers paramete= rs from zero. - Named parameters are identifiers of the form = :name in = - the query string. The advantages of named parameters a= re: - - - - - - named parameters are insensitive to the order = they occur in the - query string - - - - - they may occur multiple times in the same query - - - - - they are self-documenting - - - - - - - - - - - - - - Pagination - - - If you need to specify bounds upon your result set (th= e maximum number of rows - you want to retrieve and / or the first row you want t= o retrieve) you should - use methods of the Query interface: - - - - - - Hibernate knows how to translate this limit query into= the native - SQL of your DBMS. - - - - - - Scrollable iteration - - - If your JDBC driver supports scrollable Resul= tSets, the - Query interface may be used to obta= in a - ScrollableResults object, which all= ows flexible - navigation of the query results. - - - i++ ) && cats.next() ) pageOfCats.add( cats.get(1= ) ); - -} -cats.close()]]> - - - Note that an open database connection (and cursor) is = required for this - functionality, use setMaxResult()/<= literal>setFirstResult() - if you need offline pagination functionality. - - - - - - Externalizing named queries - - - You may also define named queries in the mapping docum= ent. (Remember to use a - CDATA section if your query contain= s characters that could - be interpreted as markup.) - - - ? -] ]>]]> - - - Parameter binding and executing is done programaticall= y: - - - - - - Note that the actual program code is independent of th= e query language that - is used, you may also define native SQL queries in met= adata, or migrate - existing queries to Hibernate by placing them in mappi= ng files. - - - - Also note that a query declaration inside a &= lt;hibernate-mapping> - element requires a global unique name for the query, w= hile a query declaration inside a - <class> element is made uniqu= e automatically by prepending the - fully qualified name of the class, for example - eg.Cat.ByNameAndMaximumWeight. - - - - - - - - Filtering collections - - A collection filter is a special type= of query that may be applied to - a persistent collection or array. The query string may ref= er to this, - meaning the current collection element. - - - - = - - The returned collection is considered a bag, and it's a co= py of the given - collection. The original collection is not modified (this = is contrary to - the implication of the name "filter", but consistent with = expected behavior). - - - - Observe that filters do not require a from clause (though they may have - one if required). Filters are not limited to returning the= collection elements themselves. - - - - - - Even an empty filter query is useful, e.g. to load a subse= t of elements in a - huge collection: - - - - - - - - Criteria queries - - - HQL is extremely powerful but some developers prefer to bu= ild queries dynamically, - using an object-oriented API, rather than building query s= trings. Hibernate provides - an intuitive Criteria query API for the= se cases: - - - - = - - The Criteria and the associated Example - API are discussed in more detail in . - - - - - - Queries in native SQL - - - You may express a query in SQL, using createSQLQu= ery() and - let Hibernate take care of the mapping from result sets to= objects. Note - that you may at any time call session.connection(= ) and - use the JDBC Connection directly. If yo= u chose to use the - Hibernate API, you must enclose SQL aliases in braces: - - - - = - - - - SQL queries may contain named and positional parameters, j= ust like Hibernate queries. - More information about native SQL queries in Hibernate can= be found in - . - - - - - - - - Modifying persistent objects - - - Transactional persistent instances (ie. o= bjects loaded, saved, created or - queried by the Session) may be manipulated = by the application - and any changes to persistent state will be persisted when the= Session - is flushed (discussed later in this chapt= er). There is no need - to call a particular method (like update(),= which has a different - purpose) to make your modifications persistent. So the most st= raightforward way to update - the state of an object is to load() it, - and then manipulate it directly, while the Session is open: - - - - - - Sometimes this programming model is inefficient since it would= require both an SQL - SELECT (to load an object) and an SQL UPDATE - (to persist its updated state) in the same session. Therefore = Hibernate offers an - alternate approach, using detached instances. - - - - Note that Hibernate does not offer its own API for d= irect execution of - UPDATE or DELETE stateme= nts. Hibernate is a - state management service, you don't have = to think in - statements to use it. JDBC is a perfect A= PI for executing - SQL statements, you can get a JDBC Connection at any time - by calling session.connection(). Furthermor= e, the notion - of mass operations conflicts with object/relational mapping fo= r online - transaction processing-oriented applications. Future versions = of Hibernate - may however provide special mass operation functions. See - for some possible batch operation tricks. - - - - - - Modifying detached objects - - - Many applications need to retrieve an object in one transactio= n, send it to the - UI layer for manipulation, then save the changes in a new tran= saction. - Applications that use this kind of approach in a high-concurre= ncy environment - usually use versioned data to ensure isolation for the "long"= unit of work. - - - - Hibernate supports this model by providing for reattachment of= detached instances - using the Session.update() or Sess= ion.merge() - methods: - - - - - - If the Cat with identifier catId had already - been loaded by secondSession when the appl= ication tried to - reattach it, an exception would have been thrown. - - - - Use update() if you are sure that the sessi= on does - not contain an already persistent instance with the same ident= ifier, and - merge() if you want to merge your modificat= ions at any time - without consideration of the state of the session. In other wo= rds, update() - is usually the first method you would call in a fresh session,= ensuring that - reattachment of your detached instances is the first operation= that is executed. - - - - The application should individually update() detached instances - reachable from the given detached instance if and on= ly if it wants - their state also updated. This can be automated of course, usi= ng transitive - persistence, see . - - - - The lock() method also allows an applicatio= n to reassociate - an object with a new session. However, the detached instance h= as to be unmodified! - - - - - - Note that lock() can be used with various - LockModes, see the API documentation and the - chapter on transaction handling for more information. Reattach= ment is not - the only usecase for lock(). - - - - Other models for long units of work are discussed in . - - - - - - Automatic state detection - - - Hibernate users have requested a general purpose method that e= ither saves a - transient instance by generating a new identifier or updates/r= eattaches - the detached instances associated with its current identifier. - The saveOrUpdate() method implements this f= unctionality. - - - - - - The usage and semantics of saveOrUpdate() s= eems to be confusing - for new users. Firstly, so long as you are not trying to use i= nstances from one session - in another new session, you should not need to use up= date(), - saveOrUpdate(), or merge(). Some whole - applications will never use either of these methods. - - - - Usually update() or saveOrUpdate()= are used in - the following scenario: - - - - - - the application loads an object in the first session - - - - - the object is passed up to the UI tier - - - - - some modifications are made to the object - - - - - the object is passed back down to the business logic t= ier - - - - - the application persists these modifications by calling - update() in a second session - - - - - - saveOrUpdate() does the following: - - - - - - if the object is already persistent in this session, d= o nothing - - - - - if another object associated with the session has the = same identifier, = - throw an exception - - - - - if the object has no identifier property, sav= e() it - - - - - if the object's identifier has the value assigned to a= newly instantiated - object, save() it - - - - - if the object is versioned (by a <version&= gt; or - <timestamp>), and the version= property value - is the same value assigned to a newly instantiated obj= ect, = - save() it - - - - - otherwise update() the object - - - - - - and merge() is very different: - - - - - - if there is a persistent instance with the same identi= fier currently = - associated with the session, copy the state of the giv= en object onto = - the persistent instance - - - - - if there is no persistent instance currently associate= d with the session, = - try to load it from the database, or create a new pers= istent instance - - - - - the persistent instance is returned - - - - - the given instance does not become associated with the= session, it - remains detached - - - - - - - - Deleting persistent objects - - - Session.delete() will remove an object's st= ate from the database. - Of course, your application might still hold a reference to a = deleted object. - It's best to think of delete() as making a = persistent instance - transient. - - - - - - You may delete objects in any order you like, without risk of = foreign key - constraint violations. It is still possible to violate a NOT - NULL constraint on a foreign key column by deleting = objects in - the wrong order, e.g. if you delete the parent, but forget to = delete the - children. - - - - = - - Replicating object between two different datastores - = - - It is occasionally useful to be able to take a graph of persisten= t instances - and make them persistent in a different datastore, without regene= rating identifier - values. - - = - - - - The ReplicationMode determines how replicate() - will deal with conflicts with existing rows in the database. - - = - - - - ReplicationMode.IGNORE - ignore the= object when there is - an existing database row with the same identifier - - - - - ReplicationMode.OVERWRITE - overwri= te any existing database = - row with the same identifier - - - - - ReplicationMode.EXCEPTION - throw a= n exception if there is - an existing database row with the same identifier - - - - - ReplicationMode.LATEST_VERSION - ov= erwrite the row if its - version number is earlier than the version number of t= he object, or ignore - the object otherwise - - - - - - Usecases for this feature include reconciling data entered int= o different database - instances, upgrading system configuration information during p= roduct upgrades, - rolling back changes made during non-ACID transactions and mor= e. - - = - - - - Flushing the Session - - - From time to time the Session will execute = the SQL statements = - needed to synchronize the JDBC connection's state with the sta= te of objects held in = - memory. This process, flush, occurs by de= fault at the following = - points - - - - - - before some query executions - - - - - from org.hibernate.Transaction.commit() - - - - - from Session.flush() - - - - - - The SQL statements are issued in the following order - - - - - - all entity insertions, in the same order the correspon= ding objects - were saved using Session.save() - - - - - all entity updates - - - - - all collection deletions - - - - - all collection element deletions, updates and insertio= ns - - - - - all collection insertions - - - - - all entity deletions, in the same order the correspond= ing objects - were deleted using Session.delete() - - - - - - (An exception is that objects using native = ID generation are = - inserted when they are saved.) - - - - Except when you explicity flush(), there ar= e absolutely no = - guarantees about when the Sessio= n executes = - the JDBC calls, only the order in which t= hey are executed. - However, Hibernate does guarantee that the Query.list= (..) = - will never return stale data; nor will they return the wrong d= ata. - - - - It is possible to change the default behavior so that flush oc= curs less frequently. - The FlushMode class defines three different= modes: only flush - at commit time (and only when the Hibernate Transacti= on API - is used), flush automatically using the explained routine, or = never flush unless - flush() is called explicitly. The last mode= is useful for long running - units of work, where a Session is kept open= and disconnected for - a long time (see ). - - - - - - During flush, an exception might occur (e.g. if a DML operatio= n violates a constraint). - Since handling exceptions involves some understanding of Hiber= nate's transactional = - behavior, we discuss it in . - - - - - - Transitive persistence - - - It is quite cumbersome to save, delete, or reattach individual= objects, - especially if you deal with a graph of associated objects. A c= ommon case is - a parent/child relationship. Consider the following example: - - - - If the children in a parent/child relationship would be value = typed (e.g. a collection - of addresses or strings), their life cycle would depend on the= parent and no - further action would be required for convenient "cascading" of= state changes. - When the parent is saved, the value-typed child objects are sa= ved as - well, when the parent is deleted, the children will be deleted= , etc. This - even works for operations such as the removal of a child from = the collection; - Hibernate will detect this and, since value-typed objects can'= t have shared - references, delete the child from the database. - - - - Now consider the same scenario with parent and child objects b= eing entities, - not value-types (e.g. categories and items, or parent and chil= d cats). Entities - have their own life cycle, support shared references (so remov= ing an entity from - the collection does not mean it can be deleted), and there is = by default no - cascading of state from one entity to any other associated ent= ities. Hibernate - does not implement persistence by reachability by default. - - - - For each basic operation of the Hibernate session - including = persist(), merge(), - saveOrUpdate(), delete(), lock(), refresh(), evict(), replicat= e() - there is a = - corresponding cascade style. Respectively, the cascade styles = are named create, = - merge, save-update, delete, lock, refresh, evict, replicate. If you want an = - operation to be cascaded along an association, you must indica= te that in the mapping - document. For example: - - = - ]]> - = - - Cascade styles my be combined: - - = - ]]> - = - - You may even use cascade=3D"all" to specify= that all - operations should be cascaded along the association. The defau= lt cascade=3D"none" - specifies that no operations are to be cascaded. - - = - - A special cascade style, delete-orphan, app= lies only to one-to-many - associations, and indicates that the delete() operation should - be applied to any child object that is removed from the associ= ation. - - - - - Recommendations: - - - - - - It doesn't usually make sense to enable cascade on a <= literal><many-to-one> - or <many-to-many> association= . Cascade is often useful for = - <one-to-one> and <= ;one-to-many> - associations. - - - - - If the child object's lifespan is bounded by the lifes= pan of the parent - object, make it a life cycle object by specifying - cascade=3D"all,delete-orphan". - - - - - Otherwise, you might not need cascade at all. But if y= ou think that you will often be - working with the parent and children together in the s= ame transaction, and you want to save = - yourself some typing, consider using cascade= =3D"persist,merge,save-update". - - - - - - Mapping an association (either a single valued association, or= a collection) with = - cascade=3D"all" marks the association as a = - parent/child style relationship where sav= e/update/delete of the = - parent results in save/update/delete of the child or children. - - - Futhermore, a mere reference to a child from a persistent pare= nt will result in = - save/update of the child. This metaphor is incomplete, however= . A child which becomes = - unreferenced by its parent is not automat= ically deleted, except = - in the case of a <one-to-many> associ= ation mapped with - cascade=3D"delete-orphan". The precise sema= ntics of cascading = - operations for a parent/child relationship are as follows: - - - - - - If a parent is passed to persist(),= all children are passed to = - persist() - - - - - If a parent is passed to merge(), a= ll children are passed to = - merge() - - - - - If a parent is passed to save(), update() or = - saveOrUpdate(), all children are pa= ssed to saveOrUpdate() - - - - - If a transient or detached child becomes referenced by= a persistent parent, = - it is passed to saveOrUpdate() - - - - - If a parent is deleted, all children are passed to delete() - - - - - If a child is dereferenced by a persistent parent, nothing - special happens - the application should ex= plicitly delete = - the child if necessary - unless cascade=3D"de= lete-orphan", = - in which case the "orphaned" child is deleted. - - - - - - Finally, note that cascading of operations can be applied to a= n object graph at - call time or at flush time. All operations, - if enabled, are cascaded to associated entities reachable when= the operation is - executed. However, save-upate and = delete-orphan - are transitive for all associated entities reachable during fl= ush of the - Session. - - - - - - Usando metadados - - - O Hibernate requer um modelo muito rico a n=C3=ADvel de metada= dos de todas as entidades e tipos de = - valores. De tempos em tempos, este modelo =C3=A9 muito =C3=BAt= il =C3=A0 pr=C3=B3pria aplica=C3=A7=C3=A3o. Por exemplo, a = - aplica=C3=A7=C3=A3o pode usar o metadados do Hibernate que exe= cuta um algoritmo "inteligente" que = - compreende quais objetos podem ser copiados (por exemplo, tipo= s de valores mut=C3=A1veis) ou = - n=C3=A3o (por exemplo, tipos de valores imut=C3=A1veis e, poss= ivelmente, entidades associadas). = - - - O Hibernate exp=C3=B5e o metadados via interfaces Cla= ssMetadata - e CollectionMetadata e pela hierarquia Type. = - Inst=C3=A2ncias das interfaces de metadados podem ser obtidas = a partir do = - SessionFactory. - - - - = - - - - + + Trabalhando com objetos + + + O Hibernate =C3=A9 uma solu=C3=A7=C3=A3o completa de mapeamento ob= jeto/relacional que n=C3=A3o apenas = + poupa o desenvolvedor dos detalhes de baixo n=C3=ADvel do sistema = de gerenciamento do = + banco de dados, mas tamb=C3=A9m oferece um gerenciamento= de estado + para objetos. Isto =C3=A9, ao contr=C3=A1rio do gerenciamento de = instru=C3=A7=C3=B5es + SQL em camadas de persist=C3=AAncia JDBC/SQL comuns, uma vis=C3=A3= o natural da persist=C3=AAncia = + orientada a objetos em aplica=C3=A7=C3=B5es Java. + + + + Em outras palavras, desenvolvedores de aplica=C3=A7=C3=B5es Hibern= ate podem sempre pensar em = + rela=C3=A7=C3=A3o ao estado de seus objetos, = e n=C3=A3o necessariamente em = + rela=C3=A7=C3=A3o a execu=C3=A7=C3=A3o de instru=C3=A7=C3=B5es SQL= . Este parte =C3=A9 responsabilidade do Hibernate e = + =C3=A9 relevante aos desenvolvedores de aplica=C3=A7=C3=B5es apena= s quando est=C3=A3o ajustando = + a performance do sistema. + + + + Estado dos objetos no Hibernate + + + O Hibernate define e suporta os seguintes estados de um objeto= s: + + + + + + Transient - um objeto =C3=A9 tran= siente se ele foi instanciando = + usando apenas o operador new, e n= =C3=A3o foi associado com uma = + Session do Hibernate. Ele n=C3=A3o = ter=C3=A1 uma representa=C3=A7=C3=A3o = + persistente no banco de dados e nenhum identificador s= er=C3=A1 atribu=C3=ADdo para ele. = + Inst=C3=A2ncias transientes ser=C3=A3o destru=C3=ADdas= pelo coletor de lixo se a aplica=C3=A7=C3=A3o = + n=C3=A3o manter sua refer=C3=AAncia. Use uma = Session do Hibernate = + para tornar o objeto persistente ( e deixe o Hibernate= gerenciar as = + instru=C3=A7=C3=B5es SQL que ser=C3=A3o necess=C3=A1ri= as para executar esta transi=C3=A7=C3=A3o). + + + + + Persistent -=E2=80=93 uma inst=C3= =A2ncia persistente possui uma = + representa=C3=A7=C3=A3o no banco de dados e um identif= icador. Ele pode ter sido salvo = + ou carregado, assim, ele est=C3=A1 por defini=C3=A7=C3= =A3o no escopo de uma = + Session. O Hibernate ir=C3=A1 detec= tar qualquer mudan=C3=A7a feita a = + um objeto persistente e sincronizar o seu estado com o= banco de dados quando = + completar a unidade de trabalho. Desenvolvedores n=C3= =A3o executam instru=C3=A7=C3=B5es manuais = + de UPDATE, ou instru=C3=A7=C3=B5es = de DELETE = + quando o objeto deve ser passado para transiente. + + + + + Detached =E2=80=93 uma inst=C3=A2= ncia desaclopada =C3=A9 um objeto que = + foi persistido, mas sua Session foi= fechada. A refer=C3=AAncia = + ao objeto continua v=C3=A1lida, =C3=A9 claro, e a ins= t=C3=A2ncia destacada desaclopada pode = + ser acoplada a uma nova Session no = futuro, fazendo-o = + ( e todas as modifica=C3=A7=C3=B5es sofridas) persiste= nte novamente. Essa caracter=C3=ADstica = + possibilita um modelo de programa=C3=A7=C3=A3o para un= idades de trabalho que rodam = + durante muito tempo que requer um pensamento por tempo= do usu=C3=A1rio. Podemos = + chamar-las de transa=C3=A7=C3=B5es da aplica= =C3=A7=C3=A3o, i.e. uma unidade = + de trabalho do ponto de vista do usu=C3=A1rio. + + + + + + Agora iremos discutir os estados e suas transi=C3=A7=C3=B5es (= e os m=C3=A9todos do Hibernate que = + disparam uma transi=C3=A7=C3=A3o) em mais detalhes. + + + + + + Tornando os objetos persistentes + + + Inst=C3=A2ncias recentemente instanciadas de uma classe persis= tente s=C3=A3o = + consideradas transientes pelo Hibernate. + Podemos tornar uma inst=C3=A2ncia transiente em per= sistente + associando-a a uma sess=C3=A3o: = + + + + + + Se Cat possui um identificador gerado, o id= entificador = + =C3=A9 gerado e atribu=C3=ADdo a cat quando= save() = + for chamada. Se Cat possuir um identificado= r = + Associado, ou uma chave composta, o identif= icador deve ser = + atribu=C3=ADdo =C3=A0 inst=C3=A2ncia de cat= antes que save() = + seja chamado. Pode-se usar tamb=C3=A9m persist() ao inv=C3=A9s de = + save(), com a sem=C3=A2ntica definada no n= ovo esbo=C3=A7o do EJB3. + + = + + + + persist() makes a transient instance persistent. = + However, it doesn't guarantee that the identifier value will be assign= ed to = + the persistent instance immediately, the assignment might happen at fl= ush time. = + persist() also guarantees that it will not execute = an = + INSERT statement if it is called outside of transac= tion = + boundaries. This is useful in long-running conversations with an exten= ded = + Session/persistence context. + + + + + save() does guarantee to return an identifier. If a= n INSERT = + has to be executed to get the identifier ( e.g. "identity" generator, = not = + "sequence"), this INSERT happens immediately, no matter if you are ins= ide or = + outside of a transaction. This is problematic in a long-running conver= sation = + with an extended Session/persistence context. + + + = + + Alternativamente, pode-se atribuir o identificador usando uma = vers=C3=A3o = + sobrecarregada de save(). + + + + = + + Se o objeto persistido possuir objetos associados (e.g. a cole= =C3=A7=C3=A3o = + kittens no exemplo anterior), esses objetos= podem ser = + tornar persistente em qualquer ordem que se queira ao menos qu= e se tenha uma = + restri=C3=A7=C3=A3o NOT NULL em uma coluna = de chave estrangeira. = + Nunca h=C3=A1 risco de viola=C3=A7=C3=A3o de restri=C3=A7=C3= =B5es de chave estrangeira. Assim, = + pode-se violar uma restri=C3=A7=C3=A3o NOT NULL se = + save() for usada nos objetos em uma ordem e= rrada. + + = + + Geralmente voc=C3=AA n=C3=A3o deve se importar com esses detal= hes, muito provavelmente se = + usar=C3=A1 a caracter=C3=ADstica de persist=C3=AAnci= a transitiva do Hibernate = + para salvar os objetos associados automaticamente. Ent=C3=A3o,= enquanto uma restri=C3=A7=C3=A3o = + NOT NULL n=C3=A3o ocorrer =E2=80=93 Hiberna= te tomar=C3=A1 conta de tudo. = + Persist=C3=AAncia transitiva ser=C3=A1 discutida futuramente n= esse cap=C3=ADtulo. + + = + + + + Carregando o objetos + + + O m=C3=A9todo load() de uma Sessi= on nos = + fornece um meio para recuperar uma inst=C3=A2ncia persistente = se o identificador = + for conhecido. load() recebe uma classe do = objeto e carregar=C3=A1 + o estado em uma inst=C3=A2ncia mais recente dessa classe, no e= stado persistente. = + + + + + + + + Alternatively, you can load state into a given instance: +Alternativamente, pode-se carregar um estado em uma inst=C3=A2ncia dada: + + + + + + Repare que load() ir=C3=A1 lan=C3=A7ar uma = exce=C3=A7=C3=A3o irrecuper=C3=A1vel = + se n=C3=A3o houver na tabela no banco de dados um registro que= combine. = + Se a classe for mapeada com um proxy, load() = + simplesmente retorna um proxy n=C3=A3o inicializado e realment= e n=C3=A3o chamar=C3=A1 = + o banco de dados at=C3=A9 que um m=C3=A9todo do proxy seja inv= ocado. = + Esse comportamento =C3=A9 muito =C3=BAtil se deseja-se criar u= ma associa=C3=A7=C3=A3o = + com um objeto sem que realmente o carregue do bando de dados. = + Isto tamb=C3=A9m permite que sejam carregadas m=C3=BAltiplas i= nst=C3=A2ncias como um = + grupo se batch-size estiver para o mapeamen= to da = + classe. + + = + + Se voc=C3=AA n=C3=A3o tiver certeza da existencia do registro = no banco, voc=C3=AA deve + usar o metodo get(), que consulta o banco = + imediantamente e retorna um null se n=C3=A3o existir o registr= o. + + = + + + + Tamb=C3=A9m pode-se carregar um objeto usando SELECT = ... FOR UPDATE, = + usando um LockMode. Veja a documenta=C3=A7= =C3=A3o da API para maiores = + informa=C3=A7=C3=B5es. + + + + = + + Note that any associated instances or contained collections ar= e = + not selected FOR UPDATE, unless you decide + to specify lock or all a= s a + cascade style for the association. + + = + + O recarregamento de um objeto e todas as suas cole=C3=A7=C3=B5= es =C3=A9 poss=C3=ADvel a qualquer momento, = + usando o m=C3=A9todo refresh(). Util quando= as triggers do banco de = + dados s=C3=A3o usados para inicializar algumas propriedades d= o objeto. + + = + + + + Uma importante quest=C3=A3o geralmente aparece neste ponto: O = quanto Hibernate carrega = + do banco de dados e quantos SQL SELECT ele= ir=C3=A1 usar? Isto = + depende da estrat=C3=A9gia de recupera=C3=A7=C3=A3o<= /emphasis>usada e explicada na = + . + + + + + + Consultando + + + Se o identificador do objeto que se est=C3=A1 buscando n=C3=A3= o for conhecido, = + uma consulta ser=C3=A1 necess=C3=A1ria. O Hibernate suporta um= a linguagem de consulta = + (HQL) orientada a objetos f=C3=A1cil mas poderosa. Para cria= =C3=A7=C3=A3o via programa=C3=A7=C3=A3o = + de consultas, o Hibernate suporta caracter=C3=ADsticas sofisti= cadas de consulta = + por Crit=C3=A9rio e Exemplo (QBCe QBE). Pode-se tamb=C3=A9m ex= pressar a consulta = + por meio de SQL nativa do banco de dados, com suporte opcional= do Hibernate = + para convers=C3=A3o do conjunto de reultados em objetos. + + + + Executando consultas + + + Consultas HQL e SQL nativa s=C3=A3o representadas por uma = inst=C3=A2ncia de org.hibernate.Query. + Esta interface oferece m=C3=A9todos para associa=C3=A7=C3= =A3o de par=C3=A2metros, tratamento de conjunto de resultados, = + e para a execu=C3=A7=C3=A3o de consultas reais. Voc=C3=AA = pode obter uma Query usando a = + Session atual: + + + + + + Geralmente uma consulta =C3=A9 executada ao invocar list(), = + o resultado da consulta ser=C3=A1 carregado completamente = em uma cole=C3=A7=C3=A3o na mem=C3=B3ria. = + Inst=C3=A2ncias de entidades recuperadas por uma consulta = est=C3=A3o no estado persistente. = + O uniqueResult() oferece um atalho se v= oc=C3=AA souber de = + previamente que a consulta retornar=C3=A1 apenas um =C3=BA= nico objeto. Repare que consultas = + que fazem uso de buscas de cole=C3=A7=C3=B5es de forma ans= iosa (eager) geralmente retornam = + duplicatas dos objetos raiz ( mas com suas cole=C3=A7=C3= =B5es inicializadas ). Pode-se = + filtrar estas duplicatas atrav=C3=A9s de um simples Set. + + + + Interagindo com resultados + + + Ocasionalmente, deves-se ser capaz de atingir performa= nces melhores com = + a execu=C3=A7=C3=A3o de consultas usando o m=C3=A9todo= iterate(). = + Geralmente isso ser=C3=A1 o caso esperado apenas se as= inst=C3=A2ncias dos entidades = + reais retornadas pela consulta j=C3=A1 estiverem na se= ss=C3=A3o ou no cach=C3=A9 de segundo = + n=C3=ADvel. Caso elas ainda n=C3=A3o tenham sido armaz= enadas, iterate() = + ser=C3=A1 mais devagar do que list() e pode ser necess=C3=A1rio v=C3=A1rios = + acessos ao banco de dados para um simples consulta, ge= ralmente 1 + para a sele=C3=A7=C3=A3o inicial que retorna apenas id= entificadores, e n + consultas adicionais para inicializar as inst=C3=A2nci= as reais. + + + + + = + + Consultas que retornam tuplas + + + Algumas vezes as consultas do Hibernate retornam tupla= s de objetos, nesse caso = + cada tupla =C3=A9 retornada como um array: = = + + + + + + + + Resultados escalares + + + Consultas devem especificar uma propriedade da classe = na clausula = + select. Elas tamb=C3=A9m podem cham= ar fun=C3=A7=C3=B5es SQL de agrega=C3=A7=C3=A3os. = + Propriedades ou agrega=C3=A7=C3=B5es s=C3=A3o consider= ados resultados agregados = + ( e n=C3=A3o entidades no estado persistente). + + + + + + + + Bind parameters + + + Methods on Query are provided for b= inding values to + named parameters or JDBC-style ? pa= rameters. = + Contrary to JDBC, Hibernate numbers paramete= rs from zero. + Named parameters are identifiers of the form = :name in = + the query string. The advantages of named parameters a= re: + + + + + + named parameters are insensitive to the order = they occur in the + query string + + + + + they may occur multiple times in the same query + + + + + they are self-documenting + + + + + + + + + + + + + + Pagination + + + If you need to specify bounds upon your result set (th= e maximum number of rows + you want to retrieve and / or the first row you want t= o retrieve) you should + use methods of the Query interface: + + + + + + Hibernate knows how to translate this limit query into= the native + SQL of your DBMS. + + + + + + Scrollable iteration + + + If your JDBC driver supports scrollable Resul= tSets, the + Query interface may be used to obta= in a + ScrollableResults object, which all= ows flexible + navigation of the query results. + + + i++ ) && cats.next() ) pageOfCats.add( cats.get(1= ) ); + +} +cats.close()]]> + + + Note that an open database connection (and cursor) is = required for this + functionality, use setMaxResult()/<= literal>setFirstResult() + if you need offline pagination functionality. + + + + + + Externalizing named queries + + + You may also define named queries in the mapping docum= ent. (Remember to use a + CDATA section if your query contain= s characters that could + be interpreted as markup.) + + + ? +] ]>]]> + + + Parameter binding and executing is done programaticall= y: + + + + + + Note that the actual program code is independent of th= e query language that + is used, you may also define native SQL queries in met= adata, or migrate + existing queries to Hibernate by placing them in mappi= ng files. + + + + Also note that a query declaration inside a &= lt;hibernate-mapping> + element requires a global unique name for the query, w= hile a query declaration inside a + <class> element is made uniqu= e automatically by prepending the + fully qualified name of the class, for example + eg.Cat.ByNameAndMaximumWeight. + + + + + + + + Filtering collections + + A collection filter is a special type= of query that may be applied to + a persistent collection or array. The query string may ref= er to this, + meaning the current collection element. + + + + = + + The returned collection is considered a bag, and it's a co= py of the given + collection. The original collection is not modified (this = is contrary to + the implication of the name "filter", but consistent with = expected behavior). + + + + Observe that filters do not require a from clause (though they may have + one if required). Filters are not limited to returning the= collection elements themselves. + + + + + + Even an empty filter query is useful, e.g. to load a subse= t of elements in a + huge collection: + + + + + + + + Criteria queries + + + HQL is extremely powerful but some developers prefer to bu= ild queries dynamically, + using an object-oriented API, rather than building query s= trings. Hibernate provides + an intuitive Criteria query API for the= se cases: + + + + = + + The Criteria and the associated Example + API are discussed in more detail in . + + + + + + Queries in native SQL + + + You may express a query in SQL, using createSQLQu= ery() and + let Hibernate take care of the mapping from result sets to= objects. Note + that you may at any time call session.connection(= ) and + use the JDBC Connection directly. If yo= u chose to use the + Hibernate API, you must enclose SQL aliases in braces: + + + + = + + + + SQL queries may contain named and positional parameters, j= ust like Hibernate queries. + More information about native SQL queries in Hibernate can= be found in + . + + + + + + + + Modifying persistent objects + + + Transactional persistent instances (ie. o= bjects loaded, saved, created or + queried by the Session) may be manipulated = by the application + and any changes to persistent state will be persisted when the= Session + is flushed (discussed later in this chapt= er). There is no need + to call a particular method (like update(),= which has a different + purpose) to make your modifications persistent. So the most st= raightforward way to update + the state of an object is to load() it, + and then manipulate it directly, while the Session is open: + + + + + + Sometimes this programming model is inefficient since it would= require both an SQL + SELECT (to load an object) and an SQL UPDATE + (to persist its updated state) in the same session. Therefore = Hibernate offers an + alternate approach, using detached instances. + + + + Note that Hibernate does not offer its own API for d= irect execution of + UPDATE or DELETE stateme= nts. Hibernate is a + state management service, you don't have = to think in + statements to use it. JDBC is a perfect A= PI for executing + SQL statements, you can get a JDBC Connection at any time + by calling session.connection(). Furthermor= e, the notion + of mass operations conflicts with object/relational mapping fo= r online + transaction processing-oriented applications. Future versions = of Hibernate + may however provide special mass operation functions. See + for some possible batch operation tricks. + + + + + + Modifying detached objects + + + Many applications need to retrieve an object in one transactio= n, send it to the + UI layer for manipulation, then save the changes in a new tran= saction. + Applications that use this kind of approach in a high-concurre= ncy environment + usually use versioned data to ensure isolation for the "long"= unit of work. + + + + Hibernate supports this model by providing for reattachment of= detached instances + using the Session.update() or Sess= ion.merge() + methods: + + + + + + If the Cat with identifier catId had already + been loaded by secondSession when the appl= ication tried to + reattach it, an exception would have been thrown. + + + + Use update() if you are sure that the sessi= on does + not contain an already persistent instance with the same ident= ifier, and + merge() if you want to merge your modificat= ions at any time + without consideration of the state of the session. In other wo= rds, update() + is usually the first method you would call in a fresh session,= ensuring that + reattachment of your detached instances is the first operation= that is executed. + + + + The application should individually update() detached instances + reachable from the given detached instance if and on= ly if it wants + their state also updated. This can be automated of course, usi= ng transitive + persistence, see . + + + + The lock() method also allows an applicatio= n to reassociate + an object with a new session. However, the detached instance h= as to be unmodified! + + + + + + Note that lock() can be used with various + LockModes, see the API documentation and the + chapter on transaction handling for more information. Reattach= ment is not + the only usecase for lock(). + + + + Other models for long units of work are discussed in . + + + + + + Automatic state detection + + + Hibernate users have requested a general purpose method that e= ither saves a + transient instance by generating a new identifier or updates/r= eattaches + the detached instances associated with its current identifier. + The saveOrUpdate() method implements this f= unctionality. + + + + + + The usage and semantics of saveOrUpdate() s= eems to be confusing + for new users. Firstly, so long as you are not trying to use i= nstances from one session + in another new session, you should not need to use up= date(), + saveOrUpdate(), or merge(). Some whole + applications will never use either of these methods. + + + + Usually update() or saveOrUpdate()= are used in + the following scenario: + + + + + + the application loads an object in the first session + + + + + the object is passed up to the UI tier + + + + + some modifications are made to the object + + + + + the object is passed back down to the business logic t= ier + + + + + the application persists these modifications by calling + update() in a second session + + + + + + saveOrUpdate() does the following: + + + + + + if the object is already persistent in this session, d= o nothing + + + + + if another object associated with the session has the = same identifier, = + throw an exception + + + + + if the object has no identifier property, sav= e() it + + + + + if the object's identifier has the value assigned to a= newly instantiated + object, save() it + + + + + if the object is versioned (by a <version&= gt; or + <timestamp>), and the version= property value + is the same value assigned to a newly instantiated obj= ect, = + save() it + + + + + otherwise update() the object + + + + + + and merge() is very different: + + + + + + if there is a persistent instance with the same identi= fier currently = + associated with the session, copy the state of the giv= en object onto = + the persistent instance + + + + + if there is no persistent instance currently associate= d with the session, = + try to load it from the database, or create a new pers= istent instance + + + + + the persistent instance is returned + + + + + the given instance does not become associated with the= session, it + remains detached + + + + + + + + Deleting persistent objects + + + Session.delete() will remove an object's st= ate from the database. + Of course, your application might still hold a reference to a = deleted object. + It's best to think of delete() as making a = persistent instance + transient. + + + + + + You may delete objects in any order you like, without risk of = foreign key + constraint violations. It is still possible to violate a NOT + NULL constraint on a foreign key column by deleting = objects in + the wrong order, e.g. if you delete the parent, but forget to = delete the + children. + + + + = + + Replicating object between two different datastores + = + + It is occasionally useful to be able to take a graph of persisten= t instances + and make them persistent in a different datastore, without regene= rating identifier + values. + + = + + + + The ReplicationMode determines how replicate() + will deal with conflicts with existing rows in the database. + + = + + + + ReplicationMode.IGNORE - ignore the= object when there is + an existing database row with the same identifier + + + + + ReplicationMode.OVERWRITE - overwri= te any existing database = + row with the same identifier + + + + + ReplicationMode.EXCEPTION - throw a= n exception if there is + an existing database row with the same identifier + + + + + ReplicationMode.LATEST_VERSION - ov= erwrite the row if its + version number is earlier than the version number of t= he object, or ignore + the object otherwise + + + + + + Usecases for this feature include reconciling data entered int= o different database + instances, upgrading system configuration information during p= roduct upgrades, + rolling back changes made during non-ACID transactions and mor= e. + + = + + + + Flushing the Session + + + From time to time the Session will execute = the SQL statements = + needed to synchronize the JDBC connection's state with the sta= te of objects held in = + memory. This process, flush, occurs by de= fault at the following = + points + + + + + + before some query executions + + + + + from org.hibernate.Transaction.commit() + + + + + from Session.flush() + + + + + + The SQL statements are issued in the following order + + + + + + all entity insertions, in the same order the correspon= ding objects + were saved using Session.save() + + + + + all entity updates + + + + + all collection deletions + + + + + all collection element deletions, updates and insertio= ns + + + + + all collection insertions + + + + + all entity deletions, in the same order the correspond= ing objects + were deleted using Session.delete() + + + + + + (An exception is that objects using native = ID generation are = + inserted when they are saved.) + + + + Except when you explicity flush(), there ar= e absolutely no = + guarantees about when the Sessio= n executes = + the JDBC calls, only the order in which t= hey are executed. + However, Hibernate does guarantee that the Query.list= (..) = + will never return stale data; nor will they return the wrong d= ata. + + + + It is possible to change the default behavior so that flush oc= curs less frequently. + The FlushMode class defines three different= modes: only flush + at commit time (and only when the Hibernate Transacti= on API + is used), flush automatically using the explained routine, or = never flush unless + flush() is called explicitly. The last mode= is useful for long running + units of work, where a Session is kept open= and disconnected for + a long time (see ). + + + + + + During flush, an exception might occur (e.g. if a DML operatio= n violates a constraint). + Since handling exceptions involves some understanding of Hiber= nate's transactional = + behavior, we discuss it in . + + + + + + Transitive persistence + + + It is quite cumbersome to save, delete, or reattach individual= objects, + especially if you deal with a graph of associated objects. A c= ommon case is + a parent/child relationship. Consider the following example: + + + + If the children in a parent/child relationship would be value = typed (e.g. a collection + of addresses or strings), their life cycle would depend on the= parent and no + further action would be required for convenient "cascading" of= state changes. + When the parent is saved, the value-typed child objects are sa= ved as + well, when the parent is deleted, the children will be deleted= , etc. This + even works for operations such as the removal of a child from = the collection; + Hibernate will detect this and, since value-typed objects can'= t have shared + references, delete the child from the database. + + + + Now consider the same scenario with parent and child objects b= eing entities, + not value-types (e.g. categories and items, or parent and chil= d cats). Entities + have their own life cycle, support shared references (so remov= ing an entity from + the collection does not mean it can be deleted), and there is = by default no + cascading of state from one entity to any other associated ent= ities. Hibernate + does not implement persistence by reachability by default. + + + + For each basic operation of the Hibernate session - including = persist(), merge(), + saveOrUpdate(), delete(), lock(), refresh(), evict(), replicat= e() - there is a = + corresponding cascade style. Respectively, the cascade styles = are named create, = + merge, save-update, delete, lock, refresh, evict, replicate. If you want an = + operation to be cascaded along an association, you must indica= te that in the mapping + document. For example: + + = + ]]> + = + + Cascade styles my be combined: + + = + ]]> + = + + You may even use cascade=3D"all" to specify= that all + operations should be cascaded along the association. The defau= lt cascade=3D"none" + specifies that no operations are to be cascaded. + + = + + A special cascade style, delete-orphan, app= lies only to one-to-many + associations, and indicates that the delete() operation should + be applied to any child object that is removed from the associ= ation. + + + + + Recommendations: + + + + + + It doesn't usually make sense to enable cascade on a <= literal><many-to-one> + or <many-to-many> association= . Cascade is often useful for = + <one-to-one> and <= ;one-to-many> + associations. + + + + + If the child object's lifespan is bounded by the lifes= pan of the parent + object, make it a life cycle object by specifying + cascade=3D"all,delete-orphan". + + + + + Otherwise, you might not need cascade at all. But if y= ou think that you will often be + working with the parent and children together in the s= ame transaction, and you want to save = + yourself some typing, consider using cascade= =3D"persist,merge,save-update". + + + + + + Mapping an association (either a single valued association, or= a collection) with = + cascade=3D"all" marks the association as a = + parent/child style relationship where sav= e/update/delete of the = + parent results in save/update/delete of the child or children. + + + Futhermore, a mere reference to a child from a persistent pare= nt will result in = + save/update of the child. This metaphor is incomplete, however= . A child which becomes = + unreferenced by its parent is not automat= ically deleted, except = + in the case of a <one-to-many> associ= ation mapped with + cascade=3D"delete-orphan". The precise sema= ntics of cascading = + operations for a parent/child relationship are as follows: + + + + + + If a parent is passed to persist(),= all children are passed to = + persist() + + + + + If a parent is passed to merge(), a= ll children are passed to = + merge() + + + + + If a parent is passed to save(), update() or = + saveOrUpdate(), all children are pa= ssed to saveOrUpdate() + + + + + If a transient or detached child becomes referenced by= a persistent parent, = + it is passed to saveOrUpdate() + + + + + If a parent is deleted, all children are passed to delete() + + + + + If a child is dereferenced by a persistent parent, nothing + special happens - the application should ex= plicitly delete = + the child if necessary - unless cascade=3D"de= lete-orphan", = + in which case the "orphaned" child is deleted. + + + + + + Finally, note that cascading of operations can be applied to a= n object graph at + call time or at flush time. All operations, + if enabled, are cascaded to associated entities reachable when= the operation is + executed. However, save-upate and = delete-orphan + are transitive for all associated entities reachable during fl= ush of the + Session. + + + + + + Usando metadados + + + O Hibernate requer um modelo muito rico a n=C3=ADvel de metada= dos de todas as entidades e tipos de = + valores. De tempos em tempos, este modelo =C3=A9 muito =C3=BAt= il =C3=A0 pr=C3=B3pria aplica=C3=A7=C3=A3o. Por exemplo, a = + aplica=C3=A7=C3=A3o pode usar o metadados do Hibernate que exe= cuta um algoritmo "inteligente" que = + compreende quais objetos podem ser copiados (por exemplo, tipo= s de valores mut=C3=A1veis) ou = + n=C3=A3o (por exemplo, tipos de valores imut=C3=A1veis e, poss= ivelmente, entidades associadas). = + + + O Hibernate exp=C3=B5e o metadados via interfaces Cla= ssMetadata + e CollectionMetadata e pela hierarquia Type. = + Inst=C3=A2ncias das interfaces de metadados podem ser obtidas = a partir do = + SessionFactory. + + + + = + + + + Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/to= olset_guide.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_= guide.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/toolset_= guide.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF + Toolset Guide = Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tr= ansactions.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transact= ions.xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/transact= ions.xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,1150 +1,1148 @@ = -=EF=BB=BF=EF=BB=BF - Transa=C3=A7=C3=B5es e Concorr=C3=AAncia - - - O ponto o mais importante sobre o Hibernate e o controle de concor= r=C3=AAncia =C3=A9 que =C3=A9 muito = - f=C3=A1cil de ser compreendido. O Hibernate usa diretamente conex= =C3=B5es de JDBC e recursos de = - JTA sem adicionar nenhum comportamento de bloqueio a mais. N=C3=B3= s altamente recomendamos = - que voc=C3=AA gaste algum tempo com o JDBC, o ANSI e a especifica= =C3=A7=C3=A3o de isolamento de transa=C3=A7=C3=A3o = - de seu sistema de ger=C3=AAncia da base de dados. - - - - O Hibernate n=C3=A3o bloqueia objetos na mem=C3=B3ria. Sua aplica= =C3=A7=C3=A3o pode esperar o comportamento = - tal qual definido pelo n=C3=ADvel de isolamento de suas transa=C3= =A7=C3=B5es de banco de dados. = - Note que gra=C3=A7as ao Session, que tamb=C3=A9= m =C3=A9 um cache de escopo de = - transa=C3=A7=C3=A3o, o Hibernate fornece leituras repet=C3=ADveis = para procurar por identificadores = - e consultas de entidade (n=C3=A3o pesquisas de relat=C3=B3rios que= retornam valores escalares). - - - = - Al=C3=A9m do versionamento para o controle autom=C3=A1tico de concor= r=C3=AAncia otimista, o Hibernate = - oferece tamb=C3=A9m uma API (menor) para bloqueio pessimista de li= nhas usando a sintaxe = - SELECT FOR UPDATE. O controle de concorr=C3=AAn= cia otimista e esta = - API s=C3=A3o discutidos mais tarde neste cap=C3=ADtulo. = - - - - N=C3=B3s come=C3=A7amos a discuss=C3=A3o do controle de concorr=C3= =AAncia no Hibernate com a granularidade = - do Configuration, SessionFactory, e - Session, al=C3=A9m de transa=C3=A7=C3=B5es de b= ase de dados e conversa=C3=A7=C3=B5es longas. - - - - Session e escopos de transa=C3=A7=C3=B5es - - - Um SessionFactory =C3=A9 objeto threadsafe = compartilhado por = - todas as threads da aplica=C3=A7=C3=A3o que consome muitos rec= ursos na sua cria=C3=A7=C3=A3o. = - =C3=89 criado uma unica vez no inicio da execu=C3=A7=C3=A3o da= aplica=C3=A7=C3=A3o a partir da - inst=C3=A2ncia de uma Configuration. - - - - Uma Session =C3=A9 um objeto de baixo custo= de cria=C3=A7=C3=A3o, n=C3=A3o =C3=A9 threadsafe, = - deve ser usado uma vez, para uma =C3=BAnica requisi=C3=A7=C3= =A3o, uma conversa=C3=A7=C3=A3o, uma =C3=BAnica unidade = - do trabalho e ent=C3=A3o deve ser descartado. Um Sess= ion n=C3=A3o obter=C3=A1 um = - JDBC Connection (ou um Datasource<= /literal>) a menos que = - necessite, conseq=C3=BCentemente n=C3=A3o consome nenhum recur= so at=C3=A9 ser usado. = - - - - Para completar, voc=C3=AA tamb=C3=A9m tem que pensar sobre as = transa=C3=A7=C3=B5es de base de dados. = - Uma transa=C3=A7=C3=A3o tem que ser t=C3=A3o curta quanto poss= =C3=ADvel, para reduzir a disputa pelo = - bloqueio na base de dados. Transa=C3=A7=C3=B5es longas impedir= =C3=A3o que sua aplica=C3=A7=C3=A3o escale a = - carga altamente concorrente. Por isso, em um projeto raramente= =C3=A9 para manter = - uma transa=C3=A7=C3=A3o de base de dados aberta durante o temp= o que o usu=C3=A1rio pensa, = - at=C3=A9 que a unidade do trabalho esteja completa. - - - - Qual =C3=A9 o escopo de uma unidade de trabalho? Pode uma =C3= =BAnicoa Session = - do Hibernate gerenciar diversas transa=C3=A7=C3=B5es ou =C3=A9= esta um o relacionamento um-para-um dos = - escopos? Quando deve voc=C3=AA abrir e fechar uma Ses= sion e como voc=C3=AA = - demarca os limites da transa=C3=A7=C3=A3o? - - - - Unidade de trabalho - - - Primeiro, n=C3=A3o use o antipattern sess=C3=A3o= -por-opera=C3=A7=C3=A3o, = - isto =C3=A9, n=C3=A3o abra e n=C3=A3o feche uma S= ession para cada simples chamada = - ao banco de de dados em uma =C3=BAnica thread! Naturalment= e, o mesmo =C3=A9 verdadeiro para = - transa=C3=A7=C3=B5es. As chamadas a banco de dados em uma = aplica=C3=A7=C3=A3o s=C3=A3o feitas usando uma = - seq=C3=BC=C3=AAncia planejada, elas s=C3=A3o agrupadas em = unidades de trabalho at=C3=B4micas. = - (Veja que isso tamb=C3=A9m significa que um auto-commit de= pois de cada senten=C3=A7a SQL =C3=A9 = - in=C3=BAtil em uma aplica=C3=A7=C3=A3o, esta modalidade = =C3=A9 ideal para o trabalho ad hoc do console = - do SQL. O Hibernate impede, ou espera que o servidor de ap= lica=C3=A7=C3=A3o impessa isso, = - o uso da modalidade de auto-commit.) As transa=C3=A7=C3=B5= es nunca s=C3=A3o opcionais, toda a = - comunica=C3=A7=C3=A3o com um banco de dados tem que ocorre= r dentro de uma transa=C3=A7=C3=A3o, n=C3=A3o = - importa se voc=C3=AA vai ler ou escrever dados. Como expli= cado, o comportamento auto-commit = - para leitura de dados deve ser evitado, como muitas transa= =C3=A7=C3=B5es pequenas s=C3=A3o = - improv=C3=A1veis de executar melhor do que uma unidade cla= ramente definida do trabalho. A - =C3=BAltima op=C3=A7=C3=A3o tamb=C3=A9m muito mais manuten= =C3=ADvel e extens=C3=ADvel. - - - - O pattern mais comum em uma aplica=C3=A7=C3=A3o multi-usu= =C3=A1rio cliente/servidor =C3=A9 = - sess=C3=A3o-por-requisi=C3=A7=C3=A3o.= Neste modelo, uma requisi=C3=A7=C3=A3o do cliente =C3=A9 = - enviada ao servidor (onde a camada de persist=C3=AAncia do= Hibernate roda), uma = - Session nova do Hibernate =C3=A9 aberta= , e todas as opera=C3=A7=C3=B5es da base de = - dados s=C3=A3o executadas nesta unidade do trabalho. Logo = que o trabalho for completado = - (e a resposta para o cliente for preparada), a sess=C3=A3o= =C3=A9 descarregad e fechada. = - Voc=C3=AA usaria tamb=C3=A9m uma =C3=BAnica transa=C3=A7= =C3=A3o de base de dados para servir =C3=A0s requisi=C3=A7=C3=B5es = - dos clientes, come=C3=A7ando e commitando-o quando voc=C3= =AA abre e fecha a Session. = - O relacionamento entre os dois =C3=A9 um-para-um e este mo= delo =C3=A9 um ajuste perfeito para muitas = - aplica=C3=A7=C3=B5es. - - - - O desafio encontra-se na implementa=C3=A7=C3=A3o. O Hibern= ate fornece ger=C3=AAncia integrada da "sess=C3=A3o atual" = - para simplificar este pattern. Tudo que voc=C3=AA tem que = fazer =C3=A9 iniciar uma transa=C3=A7=C3=A3o quando uma = - requisi=C3=A7=C3=A3o tem que ser processada e termina a tr= ansa=C3=A7=C3=A3o antes que a resposta seja enviada ao = - cliente. Voc=C3=AA pode fazer onde quiser, solu=C3=A7=C3= =B5es comuns s=C3=A3o ServletFilter, = - interceptador AOP com um pointcut (ponto de corte) nos m= =C3=A9todos de servi=C3=A7o ou em um = - container de proxy/intercepta=C3=A7=C3=A3o. Um container d= e EJB =C3=A9 uma maneira padronizada para = - implementar aspectos cross-cutting tais como a demarca=C3= =A7=C3=A3o da transa=C3=A7=C3=A3o em EJB session beans, = - declarativamente com CMT. Se voc=C3=AA se decidir usar dem= arca=C3=A7=C3=A3o program=C3=A1tica de transa=C3=A7=C3=A3o, = - de preferencia a API Transaction do Hib= ernate mostrada mais adiante neste = - cap=C3=ADtulo, para f=C3=A1cilidade no uso e portabilidade= de c=C3=B3digo. = - - - - Seu c=C3=B3digo de aplica=C3=A7=C3=A3o pode acessar a "ses= s=C3=A3o atual" para processar a requisi=C3=A7=C3=A3o = - fazendo uma chamada simples a sessionFactory.get= CurrentSession() em = - qualquer lugar e com a frequencia necess=C3=A1ria. Voc=C3= =AA sempre conseguir=C3=A1 uma - Session limitada a transa=C3=A7=C3=A3o = atual. Isto tem que ser configurado = - para recurso local ou os ambientes JTA. Veja . = - - - - =C3=80s vezes =C3=A9 conveniente estender o escopo de uma = Session e de = - uma transa=C3=A7=C3=A3o do banco de dados at=C3=A9 que a "= vis=C3=A3o esteja renderizada". =C3=89 especialmente = - =C3=BAtil em aplica=C3=A7=C3=B5es servlet que utilizam uma= fase de rendenderiza=C3=A7=C3=A3o separada depois = - que a requisi=C3=A7=C3=A3o ter sido processada. Estendendo= a transa=C3=A7=C3=A3o at=C3=A9 que renderiza=C3=A7=C3=A3o da = - vis=C3=A3o esteja completa =C3=A9 f=C3=A1cil de fazer se v= oc=C3=AA implementar seu pr=C3=B3prio interceptador. = - Entretanto, n=C3=A3o se pode fazer facilmente se voc=C3=AA= confiar em EJBs com transa=C3=A7=C3=B5es = - gerenciadas por cont=C3=AAiner, porque uma transa=C3=A7=C3= =A3o ser=C3=A1 terminada quando um m=C3=A9todo de = - EJB retornar, antes da renderiza=C3=A7=C3=A3o de toda vis= =C3=A3o puder come=C3=A7ar. = - Veja o website e o f=C3=B3rum do Hibernate para dicas e ex= emplos em torno deste = - pattern Open Session in View. = - - - - - - - Longas conversa=C3=A7=C3=B5es - - - O pattern sess=C3=A3o-por-requisi=C3=A7=C3=A3o n=C3=A3o = =C3=A9 o =C3=BAnico conceito =C3=BAtil que voc=C3=AA pode usar ao projetar = - unidades de trabalho. Muitos processos de neg=C3=B3cio req= uerem uma totalidade de s=C3=A9ries de = - intera=C3=A7=C3=B5es com o usu=C3=A1rio intercaladas com a= cessos a uma base de dados. Em aplica=C3=A7=C3=B5es web = - e corporativas n=C3=A3o =C3=A9 aceit=C3=A1vel para uma tra= nsa=C3=A7=C3=A3o atrapalhe uma intera=C3=A7=C3=A3o do usu=C3=A1rio. - Considere o seguinte exemplo: - - - - - - A primeira tela de um di=C3=A1logo abre os dados c= arregado pelo usu=C3=A1rio em atrav=C3=A9s de = - Session e transa=C3=A7=C3=A3o p= articulares. O usu=C3=A1rio est=C3=A1 livre = - modificar os objetos. = - - - - - O usu=C3=A1rio clica em "Salvar" ap=C3=B3s 5 minut= os e espera suas modifica=C3=A7=C3=B5es serem persistidas; = - espera tamb=C3=A9m que ele era a =C3=BAnica pessoa= que edita esta informa=C3=A7=C3=A3o e que nenhuma = - modifica=C3=A7=C3=A3o conflitante possa ocorrer. = - - - - - - N=C3=B3s chamamos esta unidade de trabalho, do ponto da vi= s=C3=A3o do usu=C3=A1rio, executando uma = - longa conversa=C3=A7=C3=A3o (ou transa=C3=A7=C3=A3o da aplica=C3=A7=C3=A3o). = - H=C3=A1 muitas maneiras de voc=C3=AA pode implementar em s= ua aplica=C3=A7=C3=A3o. = - - - - - Uma primeira implementa=C3=A7=C3=A3o simples pode manter a= Session e a transa=C3=A7=C3=A3o = - aberta durante o tempo de intera=C3=A7=C3=A3o do usu=C3=A1= rio, com bloqueios na base de dados para impedir = - a modifica=C3=A7=C3=A3o concorrente e para garantir o isol= amento e a atomicidade. Esse =C3=A9 naturalmente = - um anti-pattern, desde que a disputa do bloqueio n=C3=A3o = permitiria o escalonameneto da = - aplica=C3=A7=C3=A3o com o n=C3=BAmero de usu=C3=A1rios con= correntes. = - - - - Claramente, n=C3=B3s temos que usar diversas transa=C3=A7= =C3=B5es para implementar a conversa=C3=A7=C3=A3o. = - Neste caso, Manter o isolamento dos processos de neg=C3=B3= cio torna-se responsabilidade = - parcial da camada da aplica=C3=A7=C3=A3o. Uma =C3=BAnica c= onversa=C3=A7=C3=A3o geralmente usa diversas transa=C3=A7=C3=B5es. = - Ela ser=C3=A1 at=C3=B4mica se somente uma destas transa=C3= =A7=C3=B5es (a =C3=BAltima) armazenar os - dados atualizados, todas as outras simplesmente leram os d= ados (por exemplo em um = - di=C3=A1logo do estilo wizard que mede diversos ciclos de = requisi=C3=A7=C3=A3o/resposta). Isto =C3=A9 mais = - f=C3=A1cil de implementar do que pode parecer, especialmen= te se voc=C3=AA usar as - caracter=C3=ADsticas do Hibernate: = - - - - - - Versionamento autom=C3=A1tico= - O Hibernate pode fazer o = - controle autom=C3=A1tico de concorr=C3=AAncia otim= ista para voc=C3=AA, ele pode = - automaticamente detectar se uma modifica=C3=A7=C3= =A3o concorrente = - ocorreu durante o tempo de intera=C3=A7=C3=A3o do = usu=C3=A1rio. Geralmente n=C3=B3s verificamos = - somente no fim da conversa=C3=A7=C3=A3o. - - - - - Detached Objects- se voc=C3= =AA se decidir usar o j=C3=A1 discutido = - pattern session-per-request, = todas as inst=C3=A2ncias carregadas = - estar=C3=A3o no estado destacado durante o tempo e= m que o usu=C3=A1rio estiver pensando. - O Hibernate permite que voc=C3=AA reatache os obje= tos e persita as modifica=C3=A7=C3=B5es, - esse pattern =C3=A9 chamado = - session-per-request-with-detached-object= s. - =C3=89 usado versionamento automatico para isolar = as modifica=C3=A7=C3=B5es concorrentes. - - - - - Extended (or Long) Session A = Session = - do Hibernate pode ser desligada da conex=C3=A3o b= =C3=A1sica do JDBC depois que a = - transa=C3=A7=C3=A3o foi commitada e ser reconectad= o quando uma nova requisi=C3=A7=C3=A3o do = - cliente ocorrer. Este pattern =C3=A9 conhecido com= o = - session-per-conversation e fa= z o reatamento uniforme = - desnecess=C3=A1rio. Versionamento autom=C3=A1tico = =C3=A9 usado para isolar modifica=C3=A7=C3=B5es = - concorrentes e a session-per-conversatio= n usualmente = - n=C3=A3o =C3=A9 permitido para ser nivelado automa= ticamente, e sim explicitamente. = - - - - - - Ambos session-per-request-with-detached-objects<= /emphasis> e - session-per-conversation possuem vant= agens e desvantagens, = - nos discutiremos mais tarde neste cap=C3=ADtulo no context= o do controle de = - concorr=C3=AAncia otimista. = - - - - - - Considerando a identidade do objeto - - - Uma aplica=C3=A7=C3=A3o pode acessar concorrentemente o me= smo estado persistente em duas = - Sessions diferentes. Entretanto, uma in= st=C3=A2ncia de uma classe = - persistente nunca =C3=A9 compartilhada entre duas inst=C3= =A2ncias Session. = - Por tanto, h=C3=A1 duas no=C3=A7=C3=B5es diferentes da ide= ntidade: = - - - - - Identidade da base de dados - - - foo.getId().equals( bar.getId() ) - - - - - Identidade da JVM - - - foo=3D=3Dbar - - - - - - - Ent=C3=A3o para os objetos acoplados a um Session= em particular - (isto =C3=A9 no escopo de um Session), = as duas no=C3=A7=C3=B5es s=C3=A3o equivalentes e a = - identidade da JVM para a identidade da base de dados =C3= =A9 garantida pelo Hibernate. Entretanto, = - quando a aplica=C3=A7=C3=A3o pode acessar concorrentemente= o "mesmo" objeto do neg=C3=B3cio (identidade = - persistente) em duas sess=C3=B5es diferentes, as duas inst= =C3=A2ncias ser=C3=A3o realmente "diferentes" - (identidade de JVM). Os conflitos s=C3=A3o resolvidos usan= do (versionamento autom=C3=A1tico) no = - flush/commit, usando abordagem otimista. = - - - - - Este caminho deixa o Hibernate e o banco dedados se preocu= parem com a concorr=C3=AAncia; tamb=C3=A9m = - fornece uma escalabilidade melhor, garantindo que a identi= dade em unidades de trabalho = - =C3=BAnico-encadeadas n=C3=A3o necessite de bloqueio dispe= ndioso ou de outros meios de sincroniza=C3=A7=C3=A3o. = - A aplica=C3=A7=C3=A3o nunca necessita sincronizar qualquer= objeto de neg=C3=B3cio t=C3=A3o longo que transpasse = - uma =C3=BAnica thread por Session. Dent= ro de uma Session a = - aplica=C3=A7=C3=A3o pode usar com seguran=C3=A7a o =3D=3D para comparar objetos. = - - - - Com tudo, uma aplica=C3=A7=C3=A3o que usa =3D=3D<= /literal> fora de uma Session, = - pode ver resultados inesperados. Isto pode ocorrer mesmo e= m alguns lugares inesperados, por = - exemplo, se voc=C3=AA colocar duas inst=C3=A2ncias desacop= ladas em um mesmo Set. = - Ambos podem ter a mesma identidade na base de dados (isto = =C3=A9 eles representam a mesma linha = - em uma tabela), mas a identidade da JVM pela defini=C3=A7= =C3=A3o n=C3=A3o garantida para inst=C3=A2ncias em estado = - desacoplado. O desenvolvedor tem que sobrescrever os m=C3= =A9todos equals() e = - hashCode() em classes persistentes e im= plementar sua pr=C3=B3pria no=C3=A7=C3=A3o da = - igualdade do objeto. Advert=C3=AAncia: nunca use o identif= icador da base de dados para implementar = - a igualdade, use atributos de neg=C3=B3cio, uma combina=C3= =A7=C3=A3o =C3=BAnica, geralmente imut=C3=A1vel. O = - identificador da base de dados mudar=C3=A1 se um objeto tr= ansiente passar para o estado persistente. = - Se a inst=C3=A2ncia transiente (geralmente junto com inst= =C3=A2ncias desacopladas) for inserida em um = - Set, mudar o hashcode quebra o contrato= do Set. = - Atributos para chaves de neg=C3=B3cio n=C3=A3o t=C3=AAm qu= e ser t=C3=A3o est=C3=A1vel quanto =C3=A0s chaves prim=C3=A1rias = - da base de dados, voc=C3=AA somente tem que garantir a est= abilidade durante o tempo que = - os objetos estiverem no mesmo Set. Veja o website do Hiber= nate para uma discuss=C3=A3o mais = - completa sobre o assunto. Note tamb=C3=A9m que esta n=C3= =A3o =C3=A9 uma caracteristica do Hibernate, = - mas simplesmente como a identidade e a igualdade do objeto= de Java t=C3=AAm que ser implementadas. = - - - - - - Edi=C3=A7=C3=B5es comuns - - - Nunca use o anti-patterns session-per-user-sess= ion ou = - session-per-application (naturalment= e, h=C3=A1 umas exce=C3=A7=C3=B5es raras a = - essa regra). Note que algumas das seguintes edi=C3=A7=C3= =B5es podem tamb=C3=A9m aparecer com patterns = - recomendados, certifique-se que tenha compreendido as imp= lica=C3=A7=C3=B5es antes de fazer = - uma decis=C3=A3o de projeto: = - - - - - - Uma Session n=C3=A3o =C3=A9 thr= eadsafe. As coisas que s=C3=A3o supostas para trabalhar = - concorrentemente, como requisi=C3=A7=C3=B5es HTTP,= session beans, ou Swing, causar=C3=A3o condi=C3=A7=C3=B5es de = - disputa se uma inst=C3=A2ncia Session for compartilhada. Se voc=C3=AA mantiver = - sua Session do Hibernate em seu= HttpSession = - (discutido mais tarde), voc=C3=AA deve considerar = sincronizar o acesso a sua sess=C3=A3o do HTTP. = - Caso contr=C3=A1rio, um usu=C3=A1rio que clica em = reload v=C3=A1rias muito rapidamente pode usar o = - mesmo Session em duas threads e= xecutando concorrentemente. - - - - - Uma exce=C3=A7=C3=A3o lan=C3=A7ada pelo Hibernate = significa que voc=C3=AA tem que dar rollback na sua = - transa=C3=A7=C3=A3o no banco de dados e fechar a <= literal>Session imediatamente = - (discutido mais tarde em maiores detalhes). Se sua= Session =C3=A9 = - limitado pela aplica=C3=A7=C3=A3o, voc=C3=AA tem q= ue parar a aplica=C3=A7=C3=A3o. Dando rollback na = - transa=C3=A7=C3=A3o no banco de dados n=C3=A3o p= =C3=B5e seus objetos do neg=C3=B3cio em um estado anterior = - que estavam no in=C3=ADcio da transa=C3=A7=C3=A3o.= Isto significa que o estado da base de dados = - e os objetos de neg=C3=B3cio perdem a sincroniza= =C3=A7=C3=A3o. Geralmente n=C3=A3o =C3=A9 um problema = - porque as exce=C3=A7=C3=B5es n=C3=A3o s=C3=A3o rec= uper=C3=A1veis e voc=C3=AA tem que iniciar ap=C3=B3s o = - rollback de qualquer maneira. - - - - - O Session guarda em cache cada = objeto que est=C3=A1 no estado persistente = - (guardado e checado para estado "sujo" pelo Hibern= ate). Isto significa que ele cresce = - infinitamente at=C3=A9 que voc=C3=AA obtenha uma O= utOfMemoryException, se voc=C3=AA o mantiver aberto = - por muito tempo ou simplesmente carregar dados dem= ais. Uma solu=C3=A7=C3=A3o =C3=A9 chamar = - clear() e evict() para controlar o cache = - da Session, mas voc=C3=AA deve = considerar uma Store Procedure = - se precisar de opera=C3=A7=C3=B5es que envolvam gr= ande volume de dados. Algumas solu=C3=A7=C3=B5es s=C3=A3o - mostradas no . Manter um= a Session aberta = - durante uma sess=C3=A3o do usu=C3=A1rio significa = tamb=C3=A9m uma probabilidade elevada de se acabar = - com dados velhos. - - - - - - - - - - Demarca=C3=A7=C3=A3o de transa=C3=A7=C3=B5es de bancos de d= ados - - - Os limites de uma transa=C3=A7=C3=A3o de banco de dados (ou si= stema) s=C3=A3o sempre necess=C3=A1rios. Nenhuma = - comunica=C3=A7=C3=A3o com o banco de dados pode ocorrer fora d= e uma transa=C3=A7=C3=A3o de banco de dados (isto = - parece confundir muitos desenvolvedores que est=C3=A3o usados = modo auto-commit). Sempre use os = - limites desobstru=C3=ADdos da transa=C3=A7=C3=A3o, at=C3=A9 me= smo para opera=C3=A7=C3=B5es somente leitura. Dependendo = - de seu n=C3=ADvel de isolamento e capacidade da base de dados = isto pode n=C3=A3o ser requerido, = - mas n=C3=A3o h=C3=A1 nenhum aspecto negativo se voc=C3=AA dema= rca sempre transa=C3=A7=C3=B5es explicitamente. = - Certamente, uma =C3=BAnica transa=C3=A7=C3=A3o ser=C3=A1 melho= r executada do que muitas transa=C3=A7=C3=B5es pequenas, = - at=C3=A9 mesmo para dados de leitura. = - - - - Uma aplica=C3=A7=C3=A3o do Hibernate pode funcionar em ambient= es n=C3=A3o gerenciados (isto =C3=A9 aplica=C3=A7=C3=B5es standalone, Web = - simples ou Swing) e ambientes gerenciados J2EE. Em um ambiente= n=C3=A3o gerenciado, o Hibernate =C3=A9 geralmente = - respons=C3=A1vel pelo seu pr=C3=B3prio pool de conex=C3=B5es. = O desenvolvedor tem que manualmente ajustar limites das = - transa=C3=A7=C3=A3os, ou seja, come=C3=A7ar, commitar, ou dar = rollback nas transa=C3=A7=C3=B5es ele mesmo. Um ambiente gerenciado = - fornece transa=C3=A7=C3=B5es gerenciadas por cont=C3=AAiner (C= MT - container-managed transactions), com um conjunto = - da transa=C3=A7=C3=B5es definido declarativamente em descritor= es de deployment de EJB session beans, por exemplo. = - A demarca=C3=A7=C3=A3o program=C3=A1tica =C3=A9 ent=C3=A3o j= =C3=A1 n=C3=A3o =C3=A9 necess=C3=A1rio. = - - - - Entretanto, =C3=A9 freq=C3=BCentemente desej=C3=A1vel manter s= ua camada de persist=C3=AAncia port=C3=A1vel entre ambientes = - de recurso locais n=C3=A3o gerenciados e sistemas que podem co= nfiar em JTA, mas usar BMT em vez de CMT. = - Em ambos os casos voc=C3=AA usaria demarca=C3=A7=C3=A3o de tra= nsa=C3=A7=C3=A3o program=C3=A1tica. O Hibernate oferece uma API = - chamada Transaction que traduz dentro do sistema de transa=C3= =A7=C3=A3o nativa de seu ambiente de deployment. = - Esta API =C3=A9 realmente opcional, mas n=C3=B3s encorajamos f= ortemente seu uso a menos que voc=C3=AA estiver = - em um CMT session bean. = - - - - Geralmente, finalizar um Sessionenvolve qua= tro fases distintas: - - - - - - flush da sess=C3=A3o - - - - - commitar a transa=C3=A7=C3=A3o - - - - - fechar a sess=C3=A3o - - - - - tratar as exce=C3=A7=C3=B5es = - - - - - - A limpeza da sess=C3=A3o j=C3=A1 foi bem discutida, agora n=C3= =B3s daremos uma olhada na demarca=C3=A7=C3=A3o da = - transa=C3=A7=C3=A3o e na manipula=C3=A7=C3=A3o de exce=C3=A7= =C3=A3o em ambientes controlados e n=C3=A3o controlados. = - - - - - Ambiente n=C3=A3o gerenciado - - - Se uma camada de persist=C3=AAncia do Hibernate roda em um= ambiente n=C3=A3o gerenciado, as conex=C3=B5es = - do banco de dados s=C3=A3o geralmente tratadas pelos pools= de conex=C3=B5es simples = - (isto =C3=A9, n=C3=A3o baseados em DataSource) dos quais o= Hibernate obt=C3=A9m as conex=C3=B5es assim = - que necessita. A maneira de se manipular uma sess=C3=A3o/t= ransa=C3=A7=C3=A3o =C3=A9 mais ou menos assim: = - - - - - - Voc=C3=AA n=C3=A3o pode chamar flush() = do Session() = - explicitamente - a chamada ao commit() = dispara automaticamente = - a sincroniza=C3=A7=C3=A3o para a sess=C3=A3o (dependendo d= o - FlushMode). Uma chamada ao close() marca o fim de uma sess=C3=A3o. = - A principal implica=C3=A7=C3=A3o do close() =C3=A9 que a conex=C3=A3o JDBC ser=C3=A1 abandonada = - pela sess=C3=A3o. Este c=C3=B3digo Java =C3=A9 port=C3=A1v= el e funciona em ambientes n=C3=A3o gerenciado e de JTA. = - - - - Uma solu=C3=A7=C3=A3o muito mais flex=C3=ADvel =C3=A9 ger= =C3=AAncia integrada de contexto da "sess=C3=A3o atual" = - do Hibernate, como descrito anteriormente: = - - - - - - Voc=C3=AA muito provavelmente nunca ver=C3=A1 estes fragme= ntos de c=C3=B3digo em uma aplica=C3=A7=C3=A3o = - regular; as exce=C3=A7=C3=B5es fatais (do sistema) devem s= empre ser pegas no "alto". = - Ou seja, o c=C3=B3digo que executa chamadas do Hibernate (= na camada de persist=C3=AAncia) = - e o c=C3=B3digo que trata RuntimeException (e geralmente pode = - somente limpar acima e na sa=C3=ADda) est=C3=A3o em camada= s diferentes. O gerenciamento do = - contexto atual feito pelo Hibernate pode significativament= e simplificar este = - projeto, como tudo que voc=C3=AA necessita =C3=A9 do acess= o a um SessionFactory. - A manipula=C3=A7=C3=A3o de exce=C3=A7=C3=A3o =C3=A9 discut= ida mais tarde neste cap=C3=ADtulo. = - - - - Note que voc=C3=AA deve selecionar org.hibernate.= transaction.JDBCTransactionFactory - (que =C3=A9 o padr=C3=A3o) e para o segundo exemplo "thread" como seu = - hibernate.current_session_context_class. - - = - - - - Usando JTA - - - Se sua camada de persist=C3=AAncia funcionar em um servido= r de aplica=C3=A7=C3=A3o (por exemplo, = - dentro dos EJB session beans), cada conex=C3=A3o do dataso= urce obtida pelo Hibernate = - automaticamente far=C3=A1 parte da transa=C3=A7=C3=A3o glo= bal de JTA. Voc=C3=AA pode tamb=C3=A9m instalar uma = - implementa=C3=A7=C3=A3o standalone de JTA e us=C3=A1-la se= m EJB. O Hibernate oferece duas estrat=C3=A9gias = - para a integra=C3=A7=C3=A3o de JTA. = - - - - Se voc=C3=AA usar bean-managed transactions (BMT - transa= =C3=A7=C3=B5es gerenciadas por bean) o Hibernate dir=C3=A1 = - ao servidor de aplica=C3=A7=C3=A3o para come=C3=A7ar e par= a terminar uma transa=C3=A7=C3=A3o de BMT se voc=C3=AA usar a API = - Transaction. Assim, o c=C3=B3digo de ger=C3=AAncia de tran= sa=C3=A7=C3=A3o =C3=A9 id=C3=AAntico ao ambiente n=C3=A3o gerenciado. = - - = - - - - Se voc=C3=AA quiser usar um Session lim= itada por transa=C3=A7=C3=A3o, isto =C3=A9, = - a funcionalidade do getCurrentSession() = para a propaga=C3=A7=C3=A3o f=C3=A1cil = - do contexto, voc=C3=AA ter=C3=A1 que usar diretamente a API= JTA UserTransaction: = - - - - - - Com CMT, a demarca=C3=A7=C3=A3o da transa=C3=A7=C3=A3o =C3= =A9 feita em descritores de deployment do session beans, = - n=C3=A3o programaticamente, conseq=C3=BCentemente, o c=C3= =B3digo =C3=A9 reduzido a: = - - - - - - Em um CMT/EJB mesmo um rollback acontece automaticamente, = desde que uma exe=C3=A7=C3=A3o RuntimeException - n=C3=A3o trat=C3=A1vel seja lan=C3=A7ada por um m=C3=A9tod= o de um session bean que informa ao cont=C3=AAiner ajustar a = - transa=C3=A7=C3=A3o global ao rollback. Isto sig= nifica que voc=C3=AA n=C3=A3o necessita usar a API = - Transaction do Hibernate em tudo com BM= T ou CMT e voc=C3=AA obt=C3=A9m a propaga=C3=A7=C3=A3o = - autom=C3=A1tica do Session "atual" limitada =C3=A0 transa= =C3=A7=C3=A3o. - - - - Veja que voc=C3=AA dever=C3=A1 escolher org.hiber= nate.transaction.JTATransactionFactory = - se voc=C3=AA usar o JTA diretamente (BMT) e org.h= ibernate.transaction.CMTTransactionFactory = - em um CMT session bean, quando voc=C3=AA configura a f=C3= =A1brica de transa=C3=A7=C3=A3o do Hibernate. Lembre-se tamb=C3=A9m de = - configurar o hibernate.transaction.manager_lookup= _class. Al=C3=A9m disso, certifique-se = - que seu hibernate.current_session_context_class ou n=C3=A3o =C3=A9 configurado (compatibilidade = - com o legado) ou =C3=A9 definido para "jta". - - - - - A opera=C3=A7=C3=A3o getCurrentSession() tem um aspecto negativo em um ambiente JTA. = - H=C3=A1 uma advert=C3=AAncia para o uso do m=C3=A9todo lib= erado de conex=C3=A3o after_statement, = - o qual =C3=A9 usado ent=C3=A3o por padr=C3=A3o. Devido a u= ma limita=C3=A7=C3=A3o simples da especifica=C3=A7=C3=A3o JTA, n=C3=A3o =C3= =A9 = - poss=C3=ADvel para o Hibernate automaticamente limpar quai= squer inst=C3=A2ncias ScrollableResults - ou Iterator abertas retornadas pelo scroll() ou - iterate(). Voc=C3=AA deve liberar o cursor subjacente da = - base de dados chamando ScrollableResults.close()<= /literal> ou - Hibernate.close(Iterator) explicitament= e de um bloco finally. = - (Claro que a maioria de aplica=C3=A7=C3=B5es podem facilme= nte evitar o uso do scroll() ou = - do iterate() em todo c=C3=B3digo provin= do do JTA ou do CMT.) = - - - - - - - Tratamento de Exce=C3=A7=C3=A3o - - - Se a Session levantar uma exce=C3=A7=C3= =A3o (incluindo qualquer = - SQLException), voc=C3=AA deve imediatam= ente dar um rollback = - na transa=C3=A7=C3=A3o do banco, chamando Session= .close() e descartando = - a inst=C3=A2ncia da Session. Certos m= =C3=A9todos da Session = - n=C3=A3o deixar=C3=A3o a sess=C3=A3o em= um estado inconsistente. Nenhuma exce=C3=A7=C3=A3o = - lan=C3=A7ada pelo Hibernate pode ser recuperada. Certifiqu= e-se que a Session - ser=C3=A1 fechada chamando close() no b= loco finally. - - - - A exce=C3=A7=C3=A3o HibernateException,= a qual envolve a maioria dos erros = - que podem ocorrer em uma camada de persist=C3=AAncia do Hi= bernate, =C3=A9 uma exce=C3=A7=C3=A3o unchecked ( - n=C3=A3o estava em umas vers=C3=B5es mais antigas de Hiber= nate). Em nossa opini=C3=A3o, n=C3=B3s n=C3=A3o devemos - for=C3=A7ar o desenvolvedor a tratar uma exce=C3=A7=C3=A3o= irrecuper=C3=A1vel em uma camada mais baixa. = - Na maioria dos sistemas, as exce=C3=A7=C3=B5es unchecked e= fatais s=C3=A3o tratadas em um dos primeiros = - frames da pilha da chamada do m=C3=A9todo (isto =C3=A9, em= umas camadas mais elevadas) e uma mensagem = - de erro =C3=A9 apresentada ao usu=C3=A1rio da aplica=C3=A7= =C3=A3o (ou a alguma outra a=C3=A7=C3=A3o apropriada =C3=A9 feita). = - Note que Hibernate pode tamb=C3=A9m lan=C3=A7ar outras exc= e=C3=A7=C3=B5es unchecked que n=C3=A3o s=C3=A3o um = - HibernateException. Estas, tamb=C3=A9m = s=C3=A3o, irrecuper=C3=A1veis e uma a=C3=A7=C3=A3o = - apropriada deve ser tomada. - - - - O Hibernate envolve SQLExceptions lan= =C3=A7adas ao interagir com a base de dados = - em um JDBCException. Na realidade, o Hi= bernate tentar=C3=A1 converter a exce=C3=A7=C3=A3o em - em uma sub classe mais significativa da JDBCExcep= tion. A = - SQLException subjacente est=C3=A1 sempr= e dispon=C3=ADvel atrav=C3=A9s de = - JDBCException.getCause(). = - - - - O Hibernate converte a SQLException em = uma sub classe = - JDBCException apropriada usando SQLExceptionConverter = - associado ao SessionFactory. Por padr=C3=A3o, o S= QLExceptionConverter =C3=A9 definido = - pelo dialeto configurado; entretanto, =C3=A9 tamb=C3=A9m p= oss=C3=ADvel conectar em uma implementa=C3=A7=C3=A3o customizada - (veja o javadoc para mais detalhes da classe SQL= ExceptionConverterFactory). = - Os subtipos padr=C3=A3o de JDBCException s=C3=A3o: - - - - - - JDBCConnectionException - indic= a um erro com a comunica=C3=A7=C3=A3o subjacente de JDBC. - - - - - SQLGrammarException - indica um= problema da gram=C3=A1tica ou da sintaxe com o SQL emitido. - - - - - ConstraintViolationException - = indica algum forma de viola=C3=A7=C3=A3o de confinamento de integridade. - - - - - LockAcquisitionException - indi= ca um erro ao adquirir um n=C3=ADvel de bloqueio necess=C3=A1rio para reali= zar a opera=C3=A7=C3=A3o de requisi=C3=A7=C3=A3o. - - - - - GenericJDBCException - uma exce= =C3=A7=C3=A3o gen=C3=A9rica que n=C3=A3o cai em algumas das outras categori= as. = - - - - - - - - Timeout de Transa=C3=A7=C3=A3o - - - Uma caracter=C3=ADstica extremamente importante fornecida = por um ambiente = - gerenciado como EJB e que nunca =C3=A9 fornecido pelo c=C3= =B3digo n=C3=A3o gerenciado =C3=A9 o timeout = - de transa=C3=A7=C3=A3o. Timeouts de transa=C3=A7=C3=A3o as= seguram que nenhuma transa=C3=A7=C3=A3o possa = - reter indefinidamente recursos enquanto n=C3=A3o retorna = nenhuma resposta ao usu=C3=A1rio. - Fora de um ambiente controlado (JTA), o Hibernate n=C3=A3o= pode fornecer inteiramente = - esta funcionalidade. Entretanto, o Hibernate pode afinal c= ontrolar as opera=C3=A7=C3=B5es = - do acesso a dados, assegurando que o n=C3=ADvel de deadloc= ks e queries do banco de = - dados com imensos resultados definidos sejam limitados pel= o timeout. Em um ambiente = - gerenciado, o Hibernate pode delegar o timeout da transa= =C3=A7=C3=A3o ao JTA. Esta funcionalidade = - =C3=A9 abstra=C3=ADda pelo objeto Transaction do Hibernate. = - - = - - - - Veja que setTimeout() n=C3=A3o pode ser= chamado em um CMT bean, = - onde os timeouts das transa=C3=A7=C3=B5es devem ser defini= dos declarativamente. - - = - - = - - - - Controle de concorr=C3=AAncia otimista - - - O =C3=BAnico caminho que =C3=A9 consistente com a elevada conc= orr=C3=AAncia e escalabilidade = - =C3=A9 controle de concorr=C3=AAncia otimista com versionament= o. Checagem de vers=C3=A3o usa = - n=C3=BAmero de vers=C3=A3o, ou timestamps, para detectar confl= itos de atualiza=C3=A7=C3=B5es (e para = - impedir atualiza=C3=A7=C3=B5es perdidas). O Hibernate fornece = tr=C3=AAs caminhos poss=C3=ADveis para = - escrever aplica=C3=A7=C3=B5es que usam concorr=C3=AAncia otimi= sta. Os casos de uso que n=C3=B3s mostramos = - est=C3=A3o no contexto de conversa=C3=A7=C3=B5es longas, mas a= checagem de vers=C3=A3o tamb=C3=A9m tem o = - benef=C3=ADcio de impedir atualiza=C3=A7=C3=B5es perdidas em = =C3=BAnicas transa=C3=A7=C3=B5es. = - - - - Checagem de vers=C3=A3o da aplica=C3=A7=C3=A3o - - - Em uma implementa=C3=A7=C3=A3o sem muita ajuda do Hibernat= e, cada intera=C3=A7=C3=A3o com o banco de dados = - ocorre em uma nova Session e o desenvol= vedor =C3=A9 respons=C3=A1vel para = - recarregar todas as inst=C3=A2ncias persistentes da base d= e dados antes de manipul=C3=A1-las. = - Este caminho for=C3=A7a a aplica=C3=A7=C3=A3o a realizar s= ua pr=C3=B3pria checagem de vers=C3=A3o para assegurar = - a conversa=C3=A7=C3=A3o do isolamento da transa=C3=A7=C3= =A3o. Este caminho =C3=A9 menos eficiente em termos de = - acesso ao banco de dados. =C3=89 a caminho mais similar a = EJBs entity. = - - - - - - A propriedade version =C3=A9 mapeada us= ando <version>, = - e o Hibernate vai increment=C3=A1-lo-=C3=A1 automaticament= e durante o flush se a entidade = - estiver alterada. - - - - Claro, se voc=C3=AA se estiver operando em um ambiente de = baixa concorr=C3=AAncia de dados = - e n=C3=A3o requerer a checagem de vers=C3=A3o, voc=C3=AA p= ode usar este caminho e apenas saltar a = - checagem de vers=C3=A3o. Nesse caso, o ultimo c= ommit realizdo =C3=A9 = - a estrat=C3=A9gia padr=C3=A3o para suas conversa=C3=A7=C3= =B5es longas. Mantenha em mente que isto pode = - confundir os usu=C3=A1rios da aplica=C3=A7=C3=A3o, assim c= omo eles podem experimentar atualiza=C3=A7=C3=B5es - perdidas sem mensagens de erro ou uma possibilidade ajusta= r mudan=C3=A7as de conflito. - - - - - Claro que, checagem manual da vers=C3=A3o =C3=A9 somente p= ratic=C3=A1vel em circunst=C3=A2ncias triviais = - e n=C3=A3o para a maioria de aplica=C3=A7=C3=B5es. Freq=C3= =BCentemente, os grafos completos de objetos = - modificados t=C3=AAm que ser verificados, n=C3=A3o somente= =C3=BAnicas inst=C3=A2ncias. O Hibernate oferece = - checagem de vers=C3=A3o autom=C3=A1tica com uma S= ession estendida ou inst=C3=A2ncias = - desatachadas como o paradigma do projeto. - - - - - - Sess=C3=A3o estendida e versionamento autom=C3=A1tico</= title> - - <para> - Uma =C3=BAnica inst=C3=A2ncia de <literal>Session</literal= > e suas inst=C3=A2ncias persistentes = - s=C3=A3o usadas para a conversa=C3=A7=C3=A3o inteira, isto= =C3=A9 conhecido como = - <emphasis>session-per-conversation</emphasis>. O Hibernate= verifica vers=C3=B5es da inst=C3=A2ncia = - no momento dio flush, lan=C3=A7ando uma exce=C3=A7=C3=A3o = se a modifica=C3=A7=C3=A3o concorrente for detectada. = - At=C3=A9 o desenvolvedor pegar e tratar essa exce=C3=A7=C3= =A3o (as op=C3=A7=C3=B5es comuns s=C3=A3o a oportunidade = - para que o usu=C3=A1rio intercale as mudan=C3=A7as ou rein= icie a conversa=C3=A7=C3=A3o do neg=C3=B3cio com = - dados n=C3=A3o antigos). = - </para> - - <para> - The <literal>Session</literal> is disconnected from any un= derlying JDBC connection - when waiting for user interaction. This approach is the mo= st efficient in terms - of database access. The application need not concern itsel= f with version checking or - with reattaching detached instances, nor does it have to r= eload instances in every - database transaction. - A <literal>Session</literal> =C3=A9 desconectada de toda a= conex=C3=A3o JDBC subjacente = - enquanto espera a intera=C3=A7=C3=A3o do usu=C3=A1rio. Est= e caminho =C3=A9 a mais eficiente em termos = - de acesso a bancos de dados. A aplica=C3=A7=C3=A3o n=C3=A3= o necessita concernir-se com a checagem = - de vers=C3=A3o ou com as inst=C3=A2ncias destacadas reatad= as, nem tem que recarregar inst=C3=A2ncias = - em cada transa=C3=A7=C3=A3o. - </para> - - <programlisting><![CDATA[// foo is an instance loaded earlier = by the old session -Transaction t =3D session.beginTransaction(); // Obtain a new JDBC connect= ion, start transaction - -foo.setProperty("bar"); - -session.flush(); // Only for last transaction in conversation -t.commit(); // Also return JDBC connection -session.close(); // Only for last transaction in conversation]]></progr= amlisting> - <para> - O objeto <literal>foo</literal> sabe que <literal>Session<= /literal> j=C3=A1 foi carregada. Come=C3=A7ando = - uma nova transa=C3=A7=C3=A3o em uma sess=C3=A3o velha obt= =C3=A9m uma conex=C3=A3o nova e recome=C3=A7a a sess=C3=A3o. Commitando = - uma transa=C3=A7=C3=A3o desconecta uma sess=C3=A3o da cone= x=C3=A3o JDBC e retorna a conex=C3=A3o ao pool. Ap=C3=B3s a reconex=C3=A3o, = - for=C3=A7ar uma checagem de vers=C3=A3o em dados que voc= =C3=AA n=C3=A3o est=C3=A1 atualizando, voc=C3=AA pode chamar = - <literal>Session.lock()</literal> com o <literal>LockMode.= READ</literal> em todos os objetos = - que possam ter sido atualizados por uma outra transa=C3=A7= =C3=A3o. Voc=C3=AA n=C3=A3o necessita bloquear nenhum = - dado para atualizar. Geralmente voc=C3=AA configuraria <li= teral>FlushMode.MANUAL</literal> em uma - <literal>Session</literal> estendida, de modo que somente = o =C3=BAltimo ciclo da transa=C3=A7=C3=A3o tenha - permiss=C3=A3o de persistir todas as modifica=C3=A7=C3=B5e= s feitas nesta conversa=C3=A7=C3=A3o. Disso, somente esta =C3=BAltima = - transa=C3=A7=C3=A3o incluiria a opera=C3=A7=C3=A3o <litera= l>flush()</literal> e ent=C3=A3o chamar tamb=C3=A9m <literal>close()</liter= al> - da sess=C3=A3o para terminar a conversa=C3=A7=C3=A3o. - </para> - = - <para> - Este pattern =C3=A9 problem=C3=A1tico se a <literal>Sessio= n</literal> for demasiadamente grande para - ser armazenado durante o tempo que usu=C3=A1rio pensar, po= r exemplo um <literal>HttpSession</literal> = - estiver mantido t=C3=A3o pequeno quanto poss=C3=ADvel. Com= o o <literal>Session</literal> =C3=A9 tamb=C3=A9m cache = - de primeiro n=C3=ADvel (imperativo) e cont=C3=A9m todos os= objetos carregados, n=C3=B3s podemos provavelmente = - usar esta estrat=C3=A9gia somente para alguns ciclos de re= quisi=C3=A7=C3=A3o/resposta. Voc=C3=AA deve usar a - <literal>Session</literal> somente para uma =C3=BAnica con= versa=C3=A7=C3=A3o, porque ela logo tamb=C3=A9m = - estar=C3=A1 com dados velhos. - </para> - - <para> - (Note que vers=C3=B5es mais atuais de Hibernate requerem a= desconex=C3=A3o e o reconex=C3=A3o expl=C3=ADcitas de = - uma <literal>Session</literal>. Estes m=C3=A9todos s=C3=A3= o desatualizados, como o in=C3=ADcio e t=C3=A9rmino de = - uma transa=C3=A7=C3=A3o tem o mesmo efeito.) - </para> - - <para> - Note tamb=C3=A9m que voc=C3=AA deve manter a <literal>Sess= ion</literal> desconectada fechada = - para a camada de persist=C3=AAncia. Ou seja, use um EJB st= ateful session bean para = - prender a <literal>Session</literal> em um ambiente do tr= =C3=AAs camadas e n=C3=A3o o = - transferir =C3=A0 camada web (ou at=C3=A9 serializ=C3=A1-l= o para uma camada separada) - para armazen=C3=A1-lo no <literal>HttpSession</literal>. - - </para> - - <para> - O pattern sess=C3=A3o estendida, ou <emphasis>session-per-= conversation</emphasis>, =C3=A9 mais = - dif=C3=ADcil de implementar com gerenciamento autom=C3=A1t= ico de sess=C3=A3o atual. Voc=C3=AA precisa fornecer = - sua pr=C3=B3pria implementa=C3=A7=C3=A3o do <literal>Curre= ntSessionContext</literal> para isto - (veja o Hibernate Wiki para exemplos). - </para> - - </sect2> - - <sect2 id=3D"transactions-optimistic-detached"> - <title>Objetos destacados e versionamento autom=C3=A1tico</tit= le> - - <para> - Cada intera=C3=A7=C3=A3o com o armazenamento persistente o= corre em uma <literal>Session</literal> nova. = - Entretanto, as mesmas inst=C3=A2ncias persistentes s=C3=A3= o reusadas para cada intera=C3=A7=C3=A3o com o banco de dados. = - A aplica=C3=A7=C3=A3o manipula o estado das inst=C3=A2ncia= s desatachadas originalmente carregadas em um outro = - <literal>Session</literal> e reata-os ent=C3=A3o usando <l= iteral>Session.update()</literal>, = - <literal>Session.saveOrUpdate()</literal> ou <literal>Sess= ion.merge()</literal>. - </para> - - <programlisting><![CDATA[// foo is an instance loaded by a pre= vious Session -foo.setProperty("bar"); -session =3D factory.openSession(); -Transaction t =3D session.beginTransaction(); -session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded = already -t.commit(); -session.close();]]></programlisting> - - <para> - Outra vez, o Hibernate verificar=C3=A1 vers=C3=B5es da ins= t=C3=A2ncia durante o flush, = - lan=C3=A7ando uma exce=C3=A7=C3=A3o se ocorrer conflitos d= e atualiza=C3=A7=C3=B5es. - </para> - - <para> - Voc=C3=AA pode tamb=C3=A9m chamar o <literal>lock()</liter= al> em vez de <literal>update()</literal> = - e usar <literal>LockMode.READ</literal> (executando uma ch= ecagem de vers=C3=A3o, ignorando = - todos os caches) se voc=C3=AA estiver certo de que o objet= o n=C3=A3o foi modificado. - </para> - - </sect2> - - <sect2 id=3D"transactions-optimistic-customizing"> - <title>Versionamento autom=C3=A1tico customizado - - - Voc=C3=AA pode desabilitar o incremento da vers=C3=A3o aut= om=C3=A1tica de Hibernate para propriedades = - e cole=C3=A7=C3=B5es particulares configurando o mapeament= o do atributo optimistic-lock - para false. O Hibernate ent=C3=A3o n=C3=A3o ir=C3=A1 incre= menta vers=C3=B5es se a propriedade estiver - modificada. - - - - Os esquemas da base de dados legada s=C3=A3o freq=C3=BCent= emente est=C3=A1ticos e n=C3=A3o podem ser modificados. = - Ou outras aplica=C3=A7=C3=B5es puderam tamb=C3=A9m acessar= a mesma base de dados e n=C3=A3o sabem tratar a = - vers=C3=A3o dos n=C3=BAmeros ou timestamps. Em ambos os ca= sos, o versionamento n=C3=A3o pode confiar em uma = - coluna particular em uma tabela. Para for=C3=A7ar uma chec= agem de vers=C3=A3o sem uma vers=C3=A3o ou mapeamento - da propriedade do timestamp com uma compara=C3=A7=C3=A3o d= o estado de todos os campos em uma linha, = - configure optimistic-lock=3D"all" no ma= peamento <class>. = - Note que isto conceitualmente =C3=A9 somente feito em trab= alhos se Hibernate puder comparar o estado = - velho e novo, isto =C3=A9, se voc=C3=AA usa um =C3=BAnico = Session longo e n=C3=A3o = - session-per-request-with-detached-objects. - - - - =C3=80s vezes a modifica=C3=A7=C3=A3o concorrente pode ser= permitida t=C3=A3o longa quanto =C3=A0s mudan=C3=A7as que = - tiveram sido feitas que n=C3=A3o sobrepuseram. Se voc=C3= =AA configurar optimistic-lock=3D"dirty" - ao mapear o <class>, o Hibernate = comparar=C3=A1 somente campos = - modificados durante o flush. - - - - Em ambos os casos, com as colunas dedicadas da vers=C3=A3o= /timestamp ou com compara=C3=A7=C3=A3o do = - campo cheio/modificados, o Hibernate usa uma =C3=BAnica de= clara=C3=A7=C3=A3o UPDATE (com uma cl=C3=A1usula = - WHERE apropriada ) por entidade para executar a checagem d= a vers=C3=A3o e atualizar a informa=C3=A7=C3=A3o. = - Se voc=C3=AA usa a persist=C3=AAncia transitiva para casca= tear o reatamento das entidades associadas, = - o Hibernate pode executar atualiza=C3=A7=C3=B5es desnecess= =C3=A1rias. Isso n=C3=A3o =C3=A9 geralmente um problema, = - mas triggers on update em um banco de= dados podem ser executados = - mesmo quando nenhuma mudan=C3=A7a foi feita nas inst=C3=A2= ncias destacadas. Voc=C3=AA pode customizar = - este comportamento configurando select-before-upd= ate=3D"true" no = - mapeamento <class>, for=C3=A7and= o o Hibernate a d=C3=A1 um SELECT nas = - inst=C3=A2ncias para assegurar-se esse as mudan=C3=A7as oc= orreram realmente, antes de atualizar = - a linha. - - - - - - - - Locking pessimista - - - N=C3=A3o se pretende que os usu=C3=A1rios gastam muitas horas = se preocupando com suas estrat=C3=A9gias de = - locking. Geralmente =C3=A9 o bastante para especificar um n=C3= =ADvel de isolamento para as conex=C3=B5es = - JDBC e ent=C3=A3o deixar simplesmente o banco de dados fazer t= odo o trabalho. Entretanto, os = - usu=C3=A1rios avan=C3=A7ados podem =C3=A0s vezes desejar obter= locks pessimistas exclusivos, ou re-obter = - locks no in=C3=ADcio de uma nova transa=C3=A7=C3=A3o. = - - - - O Hibernate usar=C3=A1 sempre o mecanismo de lock da base de d= ados, nunca trava objetos = - na mem=C3=B3ria! - - - - A classe LockMode define os diferentes n=C3= =ADveis de lock que o Hibernate = - pode adquirir. Um lock =C3=A9 obtido pelos seguintes mecanismo= s: - - - - - - - LockMode.WRITE =C3=A9 adquirido aut= omaticamente quando o Hibernate atualiza = - ou insere uma linha. - - - - - LockMode.UPGRADE pode ser adquirido= explicitamente pelo usu=C3=A1rio = - usando SELECT ... FOR UPDATE em um = banco de dados que suporte = - esse sintaxe. - - - - - LockMode.UPGRADE_NOWAIT pode ser ad= quirido explicitamente pelo usu=C3=A1rio = - usando SELECT ... FOR UPDATE NOWAIT= no Oracle. - - - - - - LockMode.READ =C3=A9 adquirido auto= maticamente quando o Hibernate l=C3=AA = - dados em um n=C3=ADvel Repeatable Read ou Serializable= isolation. Pode ser readquirido = - explicitamente pelo usu=C3=A1rio. - - - - - LockMode.NONE representa a aus=C3=AAncia do= lock. Todos os objetos mudam para = - esse estado de lock no final da Transaction. Objetos associados com a sess=C3=A3o = - atrav=C3=A9s do m=C3=A9todo update() ou saveOrUpdate() tamb=C3=A9m s=C3=A3o - inicializados com esse lock mode. - - - - - - O lock obtido "explicitamente pelo usu=C3=A1rio" se d=C3=A1 em= uma das seguintes maneiras: - - - - - - Uma chamada a Session.load(), espec= ificando = - o LockMode. - - - - - Uma chamada a Session.lock(). - - - - - Uma chamada a Query.setLockMode(). - - - - - - Se uma Session.load() =C3=A9 invocada com <= literal>UPGRADE ou - UPGRADE_NOWAIT, e o objeto requisitado aind= a n=C3=A3o foi carregado = - pela sess=C3=A3o, o objeto =C3=A9 carregado usando SE= LECT ... FOR UPDATE. = - Se load() for chamado para um objeto que j= =C3=A1 foi carregado = - com um lock menos restritivo que o novo lock solicitado, o Hib= ernate invoca o = - m=C3=A9todo lock() para aquele objeto. - - - - O m=C3=A9todo Session.lock() executa uma v= erifica=C3=A7=C3=A3o no n=C3=BAmero da vers=C3=A3o = - se o modo de lock especificado for READ, UPGRADE ou - UPGRADE_NOWAIT.. (No caso do UPGRA= DE ou - UPGRADE_NOWAIT, =C3=A9 usado SELEC= T ... FOR UPDATE.) - - - - Se o banco de dados n=C3=A3o suportar o lock mode solicitado, = o Hibernate vai usar um modo = - alternativo apropriado (ao inv=C3=A9s de lan=C3=A7ar uma exce= =C3=A7=C3=A3o). Isso garante que a aplica=C3=A7=C3=A3o = - vai ser port=C3=A1vel. - - - - - - Modos de liberar a Connection - - - O comportamento legado do Hibernate (2.x) em considera=C3=A7= =C3=A3o ao gerenciamento da conex=C3=A3o = - via JDBC fez com que a Session precisasse o= bter uma conex=C3=A3o = - quando ela precisasse pela primeira vez e depois manter a cone= x=C3=A3o enquanto = - a sess=C3=A3o n=C3=A3o fosse fechada. O Hibernate 3.x introduz= a id=C3=A9ia de modos de liberar a = - sess=C3=A3o, para informar a sess=C3=A3o a forma como deve man= usear a sua conex=C3=A3o JDBC. = - Veja que essa discuss=C3=A3o s=C3=B3 =C3=A9 pertinente para co= nex=C3=B5es fornecidas com um = - ConnectionProvider configurado; conex=C3=B5= es fornecidas pelo usu=C3=A1rio = - est=C3=A3o fora do escopo dessa discuss=C3=A3o. Os diferentes = modos de libera=C3=A7=C3=A3o est=C3=A3o definidos = - pelos valores da enumera=C3=A7=C3=A3o = - org.hibernate.ConnectionReleaseMode: - = - - - - - - ON_CLOSE - essencialmente =C3=A9 o = modo legado descrito acima. A sess=C3=A3o = - do Hibernate obt=C3=AAm a conex=C3=A3o quando precisar= executar alguma opera=C3=A7=C3=A3o JDBC pela = - primeira vez e mantem enquanto a conex=C3=A3o n=C3=A3o= for fechada. - - - - - AFTER_TRANSACTION =E2=80=93 informa= que a conex=C3=A3o deve ser = - liberada ap=C3=B3s a conclus=C3=A3o de uma or= g.hibernate.Transaction. - - - - - AFTER_STATEMENT (tamb=C3=A9m conhec= ida com libera=C3=A7=C3=A3o agressiva) =E2=80=93 informa = - que a conex=C3=A3o deve ser liberada ap=C3=B3s a execu= =C3=A7=C3=A3o de cada statement. A libera=C3=A7=C3=A3o agressiva = - n=C3=A3o ocorre se o statement deixa pra tr=C3=A1s alg= um recurso aberto associado com a sess=C3=A3o = - obtida; atualmente, a =C3=BAnica situa=C3=A7=C3=A3o em= que isso =C3=A9 poss=C3=ADvel =C3=A9 com o uso de = - org.hibernate.ScrollableResults. - - - - - - O par=C3=A2metro de configura=C3=A7=C3=A3o hibernate.= connection.release_mode =C3=A9 usado = - para especificar qual modo de libera=C3=A7=C3=A3o deve ser usa= do. Op=C3=A7=C3=B5es dispon=C3=ADveis: = - - - - - - auto (padr=C3=A3o) =E2=80=93 essa = op=C3=A7=C3=A3o delega ao modo de libera=C3=A7=C3=A3o retornado pelo = - m=C3=A9todo org.hibernate.transaction.Transac= tionFactory.getDefaultReleaseMode(). = - Para JTATransactionFactory, ele retorna ConnectionRele= aseMode.AFTER_STATEMENT; para = - JDBCTransactionFactory, ele retorna ConnectionReleaseM= ode.AFTER_TRANSACTION. = - Raramente =C3=A9 uma boa id=C3=A9ia alterar padr=C3=A3= o, como frequencia ao se fazer isso temos falhas = - que parecem bugs e/ou suposi=C3=A7=C3=B5es inv=C3=A1li= das no c=C3=B3digo do usu=C3=A1rio. - - - - - on_close - indica o uso da Connecti= onReleaseMode.ON_CLOSE. Essa op=C3=A7=C3=A3o = - foi deixada para manter a compatibilidade, mas seu uso= =C3=A9 fortemente desencorajado. - - - - - after_transaction =E2=80=93 indica = o uso da ConnectionReleaseMode.AFTER_TRANSACTION. = - Essa op=C3=A7=C3=A3o nada deve ser usada com ambientes= JTA. Tamb=C3=A9m note que no caso da = - ConnectionReleaseMode.AFTER_TRANSACTION, se a sess=C3= =A3o foi colocada no modo auto-commit a = - conex=C3=A3o vai ser liberada de forma similar ao modo= AFTER_STATEMENT. - - - - - after_statement =E2=80=93 indica o = uso ConnectionReleaseMode.AFTER_STATEMENT. = - Adicionalmente, o ConnectionProvider configurado =C3=A9 consultado para = - verificar se suporta essa configura=C3=A7=C3=A3o ((supportsAggressiveRelease()). = - Se n=C3=A3o suportar, o modo de libera=C3=A7=C3=A3o = =C3=A9 redefinido como ConnectionRelease-Mode.AFTER_TRANSACTION. = - Essa configura=C3=A7=C3=A3o s=C3=B3 =C3=A9 segura em a= mbientes onde podemos readquirir a mesma conex=C3=A3o JDBC = - toda vez que o m=C3=A9todo ConnectionProvider= .getConnection() for chamado ou = - em um ambiente auto-commit onde n=C3=A3o importa se n= =C3=B3s recuperamos a mesma conex=C3=A3o. = - - - - - - - - + + Transa=C3=A7=C3=B5es e Concorr=C3=AAncia + + + O ponto o mais importante sobre o Hibernate e o controle de concor= r=C3=AAncia =C3=A9 que =C3=A9 muito = + f=C3=A1cil de ser compreendido. O Hibernate usa diretamente conex= =C3=B5es de JDBC e recursos de = + JTA sem adicionar nenhum comportamento de bloqueio a mais. N=C3=B3= s altamente recomendamos = + que voc=C3=AA gaste algum tempo com o JDBC, o ANSI e a especifica= =C3=A7=C3=A3o de isolamento de transa=C3=A7=C3=A3o = + de seu sistema de ger=C3=AAncia da base de dados. + + + + O Hibernate n=C3=A3o bloqueia objetos na mem=C3=B3ria. Sua aplica= =C3=A7=C3=A3o pode esperar o comportamento = + tal qual definido pelo n=C3=ADvel de isolamento de suas transa=C3= =A7=C3=B5es de banco de dados. = + Note que gra=C3=A7as ao Session, que tamb=C3=A9= m =C3=A9 um cache de escopo de = + transa=C3=A7=C3=A3o, o Hibernate fornece leituras repet=C3=ADveis = para procurar por identificadores = + e consultas de entidade (n=C3=A3o pesquisas de relat=C3=B3rios que= retornam valores escalares). + + + = + Al=C3=A9m do versionamento para o controle autom=C3=A1tico de concor= r=C3=AAncia otimista, o Hibernate = + oferece tamb=C3=A9m uma API (menor) para bloqueio pessimista de li= nhas usando a sintaxe = + SELECT FOR UPDATE. O controle de concorr=C3=AAn= cia otimista e esta = + API s=C3=A3o discutidos mais tarde neste cap=C3=ADtulo. = + + + + N=C3=B3s come=C3=A7amos a discuss=C3=A3o do controle de concorr=C3= =AAncia no Hibernate com a granularidade = + do Configuration, SessionFactory, e + Session, al=C3=A9m de transa=C3=A7=C3=B5es de b= ase de dados e conversa=C3=A7=C3=B5es longas. + + + + Session e escopos de transa=C3=A7=C3=B5es + + + Um SessionFactory =C3=A9 objeto threadsafe = compartilhado por = + todas as threads da aplica=C3=A7=C3=A3o que consome muitos rec= ursos na sua cria=C3=A7=C3=A3o. = + =C3=89 criado uma unica vez no inicio da execu=C3=A7=C3=A3o da= aplica=C3=A7=C3=A3o a partir da + inst=C3=A2ncia de uma Configuration. + + + + Uma Session =C3=A9 um objeto de baixo custo= de cria=C3=A7=C3=A3o, n=C3=A3o =C3=A9 threadsafe, = + deve ser usado uma vez, para uma =C3=BAnica requisi=C3=A7=C3= =A3o, uma conversa=C3=A7=C3=A3o, uma =C3=BAnica unidade = + do trabalho e ent=C3=A3o deve ser descartado. Um Sess= ion n=C3=A3o obter=C3=A1 um = + JDBC Connection (ou um Datasource<= /literal>) a menos que = + necessite, conseq=C3=BCentemente n=C3=A3o consome nenhum recur= so at=C3=A9 ser usado. = + + + + Para completar, voc=C3=AA tamb=C3=A9m tem que pensar sobre as = transa=C3=A7=C3=B5es de base de dados. = + Uma transa=C3=A7=C3=A3o tem que ser t=C3=A3o curta quanto poss= =C3=ADvel, para reduzir a disputa pelo = + bloqueio na base de dados. Transa=C3=A7=C3=B5es longas impedir= =C3=A3o que sua aplica=C3=A7=C3=A3o escale a = + carga altamente concorrente. Por isso, em um projeto raramente= =C3=A9 para manter = + uma transa=C3=A7=C3=A3o de base de dados aberta durante o temp= o que o usu=C3=A1rio pensa, = + at=C3=A9 que a unidade do trabalho esteja completa. + + + + Qual =C3=A9 o escopo de uma unidade de trabalho? Pode uma =C3= =BAnicoa Session = + do Hibernate gerenciar diversas transa=C3=A7=C3=B5es ou =C3=A9= esta um o relacionamento um-para-um dos = + escopos? Quando deve voc=C3=AA abrir e fechar uma Ses= sion e como voc=C3=AA = + demarca os limites da transa=C3=A7=C3=A3o? + + + + Unidade de trabalho + + + Primeiro, n=C3=A3o use o antipattern sess=C3=A3o= -por-opera=C3=A7=C3=A3o, = + isto =C3=A9, n=C3=A3o abra e n=C3=A3o feche uma S= ession para cada simples chamada = + ao banco de de dados em uma =C3=BAnica thread! Naturalment= e, o mesmo =C3=A9 verdadeiro para = + transa=C3=A7=C3=B5es. As chamadas a banco de dados em uma = aplica=C3=A7=C3=A3o s=C3=A3o feitas usando uma = + seq=C3=BC=C3=AAncia planejada, elas s=C3=A3o agrupadas em = unidades de trabalho at=C3=B4micas. = + (Veja que isso tamb=C3=A9m significa que um auto-commit de= pois de cada senten=C3=A7a SQL =C3=A9 = + in=C3=BAtil em uma aplica=C3=A7=C3=A3o, esta modalidade = =C3=A9 ideal para o trabalho ad hoc do console = + do SQL. O Hibernate impede, ou espera que o servidor de ap= lica=C3=A7=C3=A3o impessa isso, = + o uso da modalidade de auto-commit.) As transa=C3=A7=C3=B5= es nunca s=C3=A3o opcionais, toda a = + comunica=C3=A7=C3=A3o com um banco de dados tem que ocorre= r dentro de uma transa=C3=A7=C3=A3o, n=C3=A3o = + importa se voc=C3=AA vai ler ou escrever dados. Como expli= cado, o comportamento auto-commit = + para leitura de dados deve ser evitado, como muitas transa= =C3=A7=C3=B5es pequenas s=C3=A3o = + improv=C3=A1veis de executar melhor do que uma unidade cla= ramente definida do trabalho. A + =C3=BAltima op=C3=A7=C3=A3o tamb=C3=A9m muito mais manuten= =C3=ADvel e extens=C3=ADvel. + + + + O pattern mais comum em uma aplica=C3=A7=C3=A3o multi-usu= =C3=A1rio cliente/servidor =C3=A9 = + sess=C3=A3o-por-requisi=C3=A7=C3=A3o.= Neste modelo, uma requisi=C3=A7=C3=A3o do cliente =C3=A9 = + enviada ao servidor (onde a camada de persist=C3=AAncia do= Hibernate roda), uma = + Session nova do Hibernate =C3=A9 aberta= , e todas as opera=C3=A7=C3=B5es da base de = + dados s=C3=A3o executadas nesta unidade do trabalho. Logo = que o trabalho for completado = + (e a resposta para o cliente for preparada), a sess=C3=A3o= =C3=A9 descarregad e fechada. = + Voc=C3=AA usaria tamb=C3=A9m uma =C3=BAnica transa=C3=A7= =C3=A3o de base de dados para servir =C3=A0s requisi=C3=A7=C3=B5es = + dos clientes, come=C3=A7ando e commitando-o quando voc=C3= =AA abre e fecha a Session. = + O relacionamento entre os dois =C3=A9 um-para-um e este mo= delo =C3=A9 um ajuste perfeito para muitas = + aplica=C3=A7=C3=B5es. + + + + O desafio encontra-se na implementa=C3=A7=C3=A3o. O Hibern= ate fornece ger=C3=AAncia integrada da "sess=C3=A3o atual" = + para simplificar este pattern. Tudo que voc=C3=AA tem que = fazer =C3=A9 iniciar uma transa=C3=A7=C3=A3o quando uma = + requisi=C3=A7=C3=A3o tem que ser processada e termina a tr= ansa=C3=A7=C3=A3o antes que a resposta seja enviada ao = + cliente. Voc=C3=AA pode fazer onde quiser, solu=C3=A7=C3= =B5es comuns s=C3=A3o ServletFilter, = + interceptador AOP com um pointcut (ponto de corte) nos m= =C3=A9todos de servi=C3=A7o ou em um = + container de proxy/intercepta=C3=A7=C3=A3o. Um container d= e EJB =C3=A9 uma maneira padronizada para = + implementar aspectos cross-cutting tais como a demarca=C3= =A7=C3=A3o da transa=C3=A7=C3=A3o em EJB session beans, = + declarativamente com CMT. Se voc=C3=AA se decidir usar dem= arca=C3=A7=C3=A3o program=C3=A1tica de transa=C3=A7=C3=A3o, = + de preferencia a API Transaction do Hib= ernate mostrada mais adiante neste = + cap=C3=ADtulo, para f=C3=A1cilidade no uso e portabilidade= de c=C3=B3digo. = + + + + Seu c=C3=B3digo de aplica=C3=A7=C3=A3o pode acessar a "ses= s=C3=A3o atual" para processar a requisi=C3=A7=C3=A3o = + fazendo uma chamada simples a sessionFactory.get= CurrentSession() em = + qualquer lugar e com a frequencia necess=C3=A1ria. Voc=C3= =AA sempre conseguir=C3=A1 uma + Session limitada a transa=C3=A7=C3=A3o = atual. Isto tem que ser configurado = + para recurso local ou os ambientes JTA. Veja . = + + + + =C3=80s vezes =C3=A9 conveniente estender o escopo de uma = Session e de = + uma transa=C3=A7=C3=A3o do banco de dados at=C3=A9 que a "= vis=C3=A3o esteja renderizada". =C3=89 especialmente = + =C3=BAtil em aplica=C3=A7=C3=B5es servlet que utilizam uma= fase de rendenderiza=C3=A7=C3=A3o separada depois = + que a requisi=C3=A7=C3=A3o ter sido processada. Estendendo= a transa=C3=A7=C3=A3o at=C3=A9 que renderiza=C3=A7=C3=A3o da = + vis=C3=A3o esteja completa =C3=A9 f=C3=A1cil de fazer se v= oc=C3=AA implementar seu pr=C3=B3prio interceptador. = + Entretanto, n=C3=A3o se pode fazer facilmente se voc=C3=AA= confiar em EJBs com transa=C3=A7=C3=B5es = + gerenciadas por cont=C3=AAiner, porque uma transa=C3=A7=C3= =A3o ser=C3=A1 terminada quando um m=C3=A9todo de = + EJB retornar, antes da renderiza=C3=A7=C3=A3o de toda vis= =C3=A3o puder come=C3=A7ar. = + Veja o website e o f=C3=B3rum do Hibernate para dicas e ex= emplos em torno deste = + pattern Open Session in View. = + + + + + + + Longas conversa=C3=A7=C3=B5es + + + O pattern sess=C3=A3o-por-requisi=C3=A7=C3=A3o n=C3=A3o = =C3=A9 o =C3=BAnico conceito =C3=BAtil que voc=C3=AA pode usar ao projetar = + unidades de trabalho. Muitos processos de neg=C3=B3cio req= uerem uma totalidade de s=C3=A9ries de = + intera=C3=A7=C3=B5es com o usu=C3=A1rio intercaladas com a= cessos a uma base de dados. Em aplica=C3=A7=C3=B5es web = + e corporativas n=C3=A3o =C3=A9 aceit=C3=A1vel para uma tra= nsa=C3=A7=C3=A3o atrapalhe uma intera=C3=A7=C3=A3o do usu=C3=A1rio. + Considere o seguinte exemplo: + + + + + + A primeira tela de um di=C3=A1logo abre os dados c= arregado pelo usu=C3=A1rio em atrav=C3=A9s de = + Session e transa=C3=A7=C3=A3o p= articulares. O usu=C3=A1rio est=C3=A1 livre = + modificar os objetos. = + + + + + O usu=C3=A1rio clica em "Salvar" ap=C3=B3s 5 minut= os e espera suas modifica=C3=A7=C3=B5es serem persistidas; = + espera tamb=C3=A9m que ele era a =C3=BAnica pessoa= que edita esta informa=C3=A7=C3=A3o e que nenhuma = + modifica=C3=A7=C3=A3o conflitante possa ocorrer. = + + + + + + N=C3=B3s chamamos esta unidade de trabalho, do ponto da vi= s=C3=A3o do usu=C3=A1rio, executando uma = + longa conversa=C3=A7=C3=A3o (ou transa=C3=A7=C3=A3o da aplica=C3=A7=C3=A3o). = + H=C3=A1 muitas maneiras de voc=C3=AA pode implementar em s= ua aplica=C3=A7=C3=A3o. = + + + + + Uma primeira implementa=C3=A7=C3=A3o simples pode manter a= Session e a transa=C3=A7=C3=A3o = + aberta durante o tempo de intera=C3=A7=C3=A3o do usu=C3=A1= rio, com bloqueios na base de dados para impedir = + a modifica=C3=A7=C3=A3o concorrente e para garantir o isol= amento e a atomicidade. Esse =C3=A9 naturalmente = + um anti-pattern, desde que a disputa do bloqueio n=C3=A3o = permitiria o escalonameneto da = + aplica=C3=A7=C3=A3o com o n=C3=BAmero de usu=C3=A1rios con= correntes. = + + + + Claramente, n=C3=B3s temos que usar diversas transa=C3=A7= =C3=B5es para implementar a conversa=C3=A7=C3=A3o. = + Neste caso, Manter o isolamento dos processos de neg=C3=B3= cio torna-se responsabilidade = + parcial da camada da aplica=C3=A7=C3=A3o. Uma =C3=BAnica c= onversa=C3=A7=C3=A3o geralmente usa diversas transa=C3=A7=C3=B5es. = + Ela ser=C3=A1 at=C3=B4mica se somente uma destas transa=C3= =A7=C3=B5es (a =C3=BAltima) armazenar os + dados atualizados, todas as outras simplesmente leram os d= ados (por exemplo em um = + di=C3=A1logo do estilo wizard que mede diversos ciclos de = requisi=C3=A7=C3=A3o/resposta). Isto =C3=A9 mais = + f=C3=A1cil de implementar do que pode parecer, especialmen= te se voc=C3=AA usar as + caracter=C3=ADsticas do Hibernate: = + + + + + + Versionamento autom=C3=A1tico= - O Hibernate pode fazer o = + controle autom=C3=A1tico de concorr=C3=AAncia otim= ista para voc=C3=AA, ele pode = + automaticamente detectar se uma modifica=C3=A7=C3= =A3o concorrente = + ocorreu durante o tempo de intera=C3=A7=C3=A3o do = usu=C3=A1rio. Geralmente n=C3=B3s verificamos = + somente no fim da conversa=C3=A7=C3=A3o. + + + + + Detached Objects- se voc=C3= =AA se decidir usar o j=C3=A1 discutido = + pattern session-per-request, = todas as inst=C3=A2ncias carregadas = + estar=C3=A3o no estado destacado durante o tempo e= m que o usu=C3=A1rio estiver pensando. + O Hibernate permite que voc=C3=AA reatache os obje= tos e persita as modifica=C3=A7=C3=B5es, + esse pattern =C3=A9 chamado = + session-per-request-with-detached-object= s. + =C3=89 usado versionamento automatico para isolar = as modifica=C3=A7=C3=B5es concorrentes. + + + + + Extended (or Long) Session A = Session = + do Hibernate pode ser desligada da conex=C3=A3o b= =C3=A1sica do JDBC depois que a = + transa=C3=A7=C3=A3o foi commitada e ser reconectad= o quando uma nova requisi=C3=A7=C3=A3o do = + cliente ocorrer. Este pattern =C3=A9 conhecido com= o = + session-per-conversation e fa= z o reatamento uniforme = + desnecess=C3=A1rio. Versionamento autom=C3=A1tico = =C3=A9 usado para isolar modifica=C3=A7=C3=B5es = + concorrentes e a session-per-conversatio= n usualmente = + n=C3=A3o =C3=A9 permitido para ser nivelado automa= ticamente, e sim explicitamente. = + + + + + + Ambos session-per-request-with-detached-objects<= /emphasis> e + session-per-conversation possuem vant= agens e desvantagens, = + nos discutiremos mais tarde neste cap=C3=ADtulo no context= o do controle de = + concorr=C3=AAncia otimista. = + + + + + + Considerando a identidade do objeto + + + Uma aplica=C3=A7=C3=A3o pode acessar concorrentemente o me= smo estado persistente em duas = + Sessions diferentes. Entretanto, uma in= st=C3=A2ncia de uma classe = + persistente nunca =C3=A9 compartilhada entre duas inst=C3= =A2ncias Session. = + Por tanto, h=C3=A1 duas no=C3=A7=C3=B5es diferentes da ide= ntidade: = + + + + + Identidade da base de dados + + + foo.getId().equals( bar.getId() ) + + + + + Identidade da JVM + + + foo=3D=3Dbar + + + + + + + Ent=C3=A3o para os objetos acoplados a um Session= em particular + (isto =C3=A9 no escopo de um Session), = as duas no=C3=A7=C3=B5es s=C3=A3o equivalentes e a = + identidade da JVM para a identidade da base de dados =C3= =A9 garantida pelo Hibernate. Entretanto, = + quando a aplica=C3=A7=C3=A3o pode acessar concorrentemente= o "mesmo" objeto do neg=C3=B3cio (identidade = + persistente) em duas sess=C3=B5es diferentes, as duas inst= =C3=A2ncias ser=C3=A3o realmente "diferentes" + (identidade de JVM). Os conflitos s=C3=A3o resolvidos usan= do (versionamento autom=C3=A1tico) no = + flush/commit, usando abordagem otimista. = + + + + + Este caminho deixa o Hibernate e o banco dedados se preocu= parem com a concorr=C3=AAncia; tamb=C3=A9m = + fornece uma escalabilidade melhor, garantindo que a identi= dade em unidades de trabalho = + =C3=BAnico-encadeadas n=C3=A3o necessite de bloqueio dispe= ndioso ou de outros meios de sincroniza=C3=A7=C3=A3o. = + A aplica=C3=A7=C3=A3o nunca necessita sincronizar qualquer= objeto de neg=C3=B3cio t=C3=A3o longo que transpasse = + uma =C3=BAnica thread por Session. Dent= ro de uma Session a = + aplica=C3=A7=C3=A3o pode usar com seguran=C3=A7a o =3D=3D para comparar objetos. = + + + + Com tudo, uma aplica=C3=A7=C3=A3o que usa =3D=3D<= /literal> fora de uma Session, = + pode ver resultados inesperados. Isto pode ocorrer mesmo e= m alguns lugares inesperados, por = + exemplo, se voc=C3=AA colocar duas inst=C3=A2ncias desacop= ladas em um mesmo Set. = + Ambos podem ter a mesma identidade na base de dados (isto = =C3=A9 eles representam a mesma linha = + em uma tabela), mas a identidade da JVM pela defini=C3=A7= =C3=A3o n=C3=A3o garantida para inst=C3=A2ncias em estado = + desacoplado. O desenvolvedor tem que sobrescrever os m=C3= =A9todos equals() e = + hashCode() em classes persistentes e im= plementar sua pr=C3=B3pria no=C3=A7=C3=A3o da = + igualdade do objeto. Advert=C3=AAncia: nunca use o identif= icador da base de dados para implementar = + a igualdade, use atributos de neg=C3=B3cio, uma combina=C3= =A7=C3=A3o =C3=BAnica, geralmente imut=C3=A1vel. O = + identificador da base de dados mudar=C3=A1 se um objeto tr= ansiente passar para o estado persistente. = + Se a inst=C3=A2ncia transiente (geralmente junto com inst= =C3=A2ncias desacopladas) for inserida em um = + Set, mudar o hashcode quebra o contrato= do Set. = + Atributos para chaves de neg=C3=B3cio n=C3=A3o t=C3=AAm qu= e ser t=C3=A3o est=C3=A1vel quanto =C3=A0s chaves prim=C3=A1rias = + da base de dados, voc=C3=AA somente tem que garantir a est= abilidade durante o tempo que = + os objetos estiverem no mesmo Set. Veja o website do Hiber= nate para uma discuss=C3=A3o mais = + completa sobre o assunto. Note tamb=C3=A9m que esta n=C3= =A3o =C3=A9 uma caracteristica do Hibernate, = + mas simplesmente como a identidade e a igualdade do objeto= de Java t=C3=AAm que ser implementadas. = + + + + + + Edi=C3=A7=C3=B5es comuns + + + Nunca use o anti-patterns session-per-user-sess= ion ou = + session-per-application (naturalment= e, h=C3=A1 umas exce=C3=A7=C3=B5es raras a = + essa regra). Note que algumas das seguintes edi=C3=A7=C3= =B5es podem tamb=C3=A9m aparecer com patterns = + recomendados, certifique-se que tenha compreendido as imp= lica=C3=A7=C3=B5es antes de fazer = + uma decis=C3=A3o de projeto: = + + + + + + Uma Session n=C3=A3o =C3=A9 thr= eadsafe. As coisas que s=C3=A3o supostas para trabalhar = + concorrentemente, como requisi=C3=A7=C3=B5es HTTP,= session beans, ou Swing, causar=C3=A3o condi=C3=A7=C3=B5es de = + disputa se uma inst=C3=A2ncia Session for compartilhada. Se voc=C3=AA mantiver = + sua Session do Hibernate em seu= HttpSession = + (discutido mais tarde), voc=C3=AA deve considerar = sincronizar o acesso a sua sess=C3=A3o do HTTP. = + Caso contr=C3=A1rio, um usu=C3=A1rio que clica em = reload v=C3=A1rias muito rapidamente pode usar o = + mesmo Session em duas threads e= xecutando concorrentemente. + + + + + Uma exce=C3=A7=C3=A3o lan=C3=A7ada pelo Hibernate = significa que voc=C3=AA tem que dar rollback na sua = + transa=C3=A7=C3=A3o no banco de dados e fechar a <= literal>Session imediatamente = + (discutido mais tarde em maiores detalhes). Se sua= Session =C3=A9 = + limitado pela aplica=C3=A7=C3=A3o, voc=C3=AA tem q= ue parar a aplica=C3=A7=C3=A3o. Dando rollback na = + transa=C3=A7=C3=A3o no banco de dados n=C3=A3o p= =C3=B5e seus objetos do neg=C3=B3cio em um estado anterior = + que estavam no in=C3=ADcio da transa=C3=A7=C3=A3o.= Isto significa que o estado da base de dados = + e os objetos de neg=C3=B3cio perdem a sincroniza= =C3=A7=C3=A3o. Geralmente n=C3=A3o =C3=A9 um problema = + porque as exce=C3=A7=C3=B5es n=C3=A3o s=C3=A3o rec= uper=C3=A1veis e voc=C3=AA tem que iniciar ap=C3=B3s o = + rollback de qualquer maneira. + + + + + O Session guarda em cache cada = objeto que est=C3=A1 no estado persistente = + (guardado e checado para estado "sujo" pelo Hibern= ate). Isto significa que ele cresce = + infinitamente at=C3=A9 que voc=C3=AA obtenha uma O= utOfMemoryException, se voc=C3=AA o mantiver aberto = + por muito tempo ou simplesmente carregar dados dem= ais. Uma solu=C3=A7=C3=A3o =C3=A9 chamar = + clear() e evict() para controlar o cache = + da Session, mas voc=C3=AA deve = considerar uma Store Procedure = + se precisar de opera=C3=A7=C3=B5es que envolvam gr= ande volume de dados. Algumas solu=C3=A7=C3=B5es s=C3=A3o + mostradas no . Manter um= a Session aberta = + durante uma sess=C3=A3o do usu=C3=A1rio significa = tamb=C3=A9m uma probabilidade elevada de se acabar = + com dados velhos. + + + + + + + + + + Demarca=C3=A7=C3=A3o de transa=C3=A7=C3=B5es de bancos de d= ados + + + Os limites de uma transa=C3=A7=C3=A3o de banco de dados (ou si= stema) s=C3=A3o sempre necess=C3=A1rios. Nenhuma = + comunica=C3=A7=C3=A3o com o banco de dados pode ocorrer fora d= e uma transa=C3=A7=C3=A3o de banco de dados (isto = + parece confundir muitos desenvolvedores que est=C3=A3o usados = modo auto-commit). Sempre use os = + limites desobstru=C3=ADdos da transa=C3=A7=C3=A3o, at=C3=A9 me= smo para opera=C3=A7=C3=B5es somente leitura. Dependendo = + de seu n=C3=ADvel de isolamento e capacidade da base de dados = isto pode n=C3=A3o ser requerido, = + mas n=C3=A3o h=C3=A1 nenhum aspecto negativo se voc=C3=AA dema= rca sempre transa=C3=A7=C3=B5es explicitamente. = + Certamente, uma =C3=BAnica transa=C3=A7=C3=A3o ser=C3=A1 melho= r executada do que muitas transa=C3=A7=C3=B5es pequenas, = + at=C3=A9 mesmo para dados de leitura. = + + + + Uma aplica=C3=A7=C3=A3o do Hibernate pode funcionar em ambient= es n=C3=A3o gerenciados (isto =C3=A9 aplica=C3=A7=C3=B5es standalone, Web = + simples ou Swing) e ambientes gerenciados J2EE. Em um ambiente= n=C3=A3o gerenciado, o Hibernate =C3=A9 geralmente = + respons=C3=A1vel pelo seu pr=C3=B3prio pool de conex=C3=B5es. = O desenvolvedor tem que manualmente ajustar limites das = + transa=C3=A7=C3=A3os, ou seja, come=C3=A7ar, commitar, ou dar = rollback nas transa=C3=A7=C3=B5es ele mesmo. Um ambiente gerenciado = + fornece transa=C3=A7=C3=B5es gerenciadas por cont=C3=AAiner (C= MT - container-managed transactions), com um conjunto = + da transa=C3=A7=C3=B5es definido declarativamente em descritor= es de deployment de EJB session beans, por exemplo. = + A demarca=C3=A7=C3=A3o program=C3=A1tica =C3=A9 ent=C3=A3o j= =C3=A1 n=C3=A3o =C3=A9 necess=C3=A1rio. = + + + + Entretanto, =C3=A9 freq=C3=BCentemente desej=C3=A1vel manter s= ua camada de persist=C3=AAncia port=C3=A1vel entre ambientes = + de recurso locais n=C3=A3o gerenciados e sistemas que podem co= nfiar em JTA, mas usar BMT em vez de CMT. = + Em ambos os casos voc=C3=AA usaria demarca=C3=A7=C3=A3o de tra= nsa=C3=A7=C3=A3o program=C3=A1tica. O Hibernate oferece uma API = + chamada Transaction que traduz dentro do sistema de transa=C3= =A7=C3=A3o nativa de seu ambiente de deployment. = + Esta API =C3=A9 realmente opcional, mas n=C3=B3s encorajamos f= ortemente seu uso a menos que voc=C3=AA estiver = + em um CMT session bean. = + + + + Geralmente, finalizar um Sessionenvolve qua= tro fases distintas: + + + + + + flush da sess=C3=A3o + + + + + commitar a transa=C3=A7=C3=A3o + + + + + fechar a sess=C3=A3o + + + + + tratar as exce=C3=A7=C3=B5es = + + + + + + A limpeza da sess=C3=A3o j=C3=A1 foi bem discutida, agora n=C3= =B3s daremos uma olhada na demarca=C3=A7=C3=A3o da = + transa=C3=A7=C3=A3o e na manipula=C3=A7=C3=A3o de exce=C3=A7= =C3=A3o em ambientes controlados e n=C3=A3o controlados. = + + + + + Ambiente n=C3=A3o gerenciado + + + Se uma camada de persist=C3=AAncia do Hibernate roda em um= ambiente n=C3=A3o gerenciado, as conex=C3=B5es = + do banco de dados s=C3=A3o geralmente tratadas pelos pools= de conex=C3=B5es simples = + (isto =C3=A9, n=C3=A3o baseados em DataSource) dos quais o= Hibernate obt=C3=A9m as conex=C3=B5es assim = + que necessita. A maneira de se manipular uma sess=C3=A3o/t= ransa=C3=A7=C3=A3o =C3=A9 mais ou menos assim: = + + + + + + Voc=C3=AA n=C3=A3o pode chamar flush() = do Session() = + explicitamente - a chamada ao commit() = dispara automaticamente = + a sincroniza=C3=A7=C3=A3o para a sess=C3=A3o (dependendo d= o + FlushMode). Uma chamada ao close() marca o fim de uma sess=C3=A3o. = + A principal implica=C3=A7=C3=A3o do close() =C3=A9 que a conex=C3=A3o JDBC ser=C3=A1 abandonada = + pela sess=C3=A3o. Este c=C3=B3digo Java =C3=A9 port=C3=A1v= el e funciona em ambientes n=C3=A3o gerenciado e de JTA. = + + + + Uma solu=C3=A7=C3=A3o muito mais flex=C3=ADvel =C3=A9 ger= =C3=AAncia integrada de contexto da "sess=C3=A3o atual" = + do Hibernate, como descrito anteriormente: = + + + + + + Voc=C3=AA muito provavelmente nunca ver=C3=A1 estes fragme= ntos de c=C3=B3digo em uma aplica=C3=A7=C3=A3o = + regular; as exce=C3=A7=C3=B5es fatais (do sistema) devem s= empre ser pegas no "alto". = + Ou seja, o c=C3=B3digo que executa chamadas do Hibernate (= na camada de persist=C3=AAncia) = + e o c=C3=B3digo que trata RuntimeException (e geralmente pode = + somente limpar acima e na sa=C3=ADda) est=C3=A3o em camada= s diferentes. O gerenciamento do = + contexto atual feito pelo Hibernate pode significativament= e simplificar este = + projeto, como tudo que voc=C3=AA necessita =C3=A9 do acess= o a um SessionFactory. + A manipula=C3=A7=C3=A3o de exce=C3=A7=C3=A3o =C3=A9 discut= ida mais tarde neste cap=C3=ADtulo. = + + + + Note que voc=C3=AA deve selecionar org.hibernate.= transaction.JDBCTransactionFactory + (que =C3=A9 o padr=C3=A3o) e para o segundo exemplo "thread" como seu = + hibernate.current_session_context_class. + + = + + + + Usando JTA + + + Se sua camada de persist=C3=AAncia funcionar em um servido= r de aplica=C3=A7=C3=A3o (por exemplo, = + dentro dos EJB session beans), cada conex=C3=A3o do dataso= urce obtida pelo Hibernate = + automaticamente far=C3=A1 parte da transa=C3=A7=C3=A3o glo= bal de JTA. Voc=C3=AA pode tamb=C3=A9m instalar uma = + implementa=C3=A7=C3=A3o standalone de JTA e us=C3=A1-la se= m EJB. O Hibernate oferece duas estrat=C3=A9gias = + para a integra=C3=A7=C3=A3o de JTA. = + + + + Se voc=C3=AA usar bean-managed transactions (BMT - transa= =C3=A7=C3=B5es gerenciadas por bean) o Hibernate dir=C3=A1 = + ao servidor de aplica=C3=A7=C3=A3o para come=C3=A7ar e par= a terminar uma transa=C3=A7=C3=A3o de BMT se voc=C3=AA usar a API = + Transaction. Assim, o c=C3=B3digo de ger=C3=AAncia de tran= sa=C3=A7=C3=A3o =C3=A9 id=C3=AAntico ao ambiente n=C3=A3o gerenciado. = + + = + + + + Se voc=C3=AA quiser usar um Session lim= itada por transa=C3=A7=C3=A3o, isto =C3=A9, = + a funcionalidade do getCurrentSession() = para a propaga=C3=A7=C3=A3o f=C3=A1cil = + do contexto, voc=C3=AA ter=C3=A1 que usar diretamente a API= JTA UserTransaction: = + + + + + + Com CMT, a demarca=C3=A7=C3=A3o da transa=C3=A7=C3=A3o =C3= =A9 feita em descritores de deployment do session beans, = + n=C3=A3o programaticamente, conseq=C3=BCentemente, o c=C3= =B3digo =C3=A9 reduzido a: = + + + + + + Em um CMT/EJB mesmo um rollback acontece automaticamente, = desde que uma exe=C3=A7=C3=A3o RuntimeException + n=C3=A3o trat=C3=A1vel seja lan=C3=A7ada por um m=C3=A9tod= o de um session bean que informa ao cont=C3=AAiner ajustar a = + transa=C3=A7=C3=A3o global ao rollback. Isto sig= nifica que voc=C3=AA n=C3=A3o necessita usar a API = + Transaction do Hibernate em tudo com BM= T ou CMT e voc=C3=AA obt=C3=A9m a propaga=C3=A7=C3=A3o = + autom=C3=A1tica do Session "atual" limitada =C3=A0 transa= =C3=A7=C3=A3o. + + + + Veja que voc=C3=AA dever=C3=A1 escolher org.hiber= nate.transaction.JTATransactionFactory = + se voc=C3=AA usar o JTA diretamente (BMT) e org.h= ibernate.transaction.CMTTransactionFactory = + em um CMT session bean, quando voc=C3=AA configura a f=C3= =A1brica de transa=C3=A7=C3=A3o do Hibernate. Lembre-se tamb=C3=A9m de = + configurar o hibernate.transaction.manager_lookup= _class. Al=C3=A9m disso, certifique-se = + que seu hibernate.current_session_context_class ou n=C3=A3o =C3=A9 configurado (compatibilidade = + com o legado) ou =C3=A9 definido para "jta". + + + + + A opera=C3=A7=C3=A3o getCurrentSession() tem um aspecto negativo em um ambiente JTA. = + H=C3=A1 uma advert=C3=AAncia para o uso do m=C3=A9todo lib= erado de conex=C3=A3o after_statement, = + o qual =C3=A9 usado ent=C3=A3o por padr=C3=A3o. Devido a u= ma limita=C3=A7=C3=A3o simples da especifica=C3=A7=C3=A3o JTA, n=C3=A3o =C3= =A9 = + poss=C3=ADvel para o Hibernate automaticamente limpar quai= squer inst=C3=A2ncias ScrollableResults + ou Iterator abertas retornadas pelo scroll() ou + iterate(). Voc=C3=AA deve liberar o cursor subjacente da = + base de dados chamando ScrollableResults.close()<= /literal> ou + Hibernate.close(Iterator) explicitament= e de um bloco finally. = + (Claro que a maioria de aplica=C3=A7=C3=B5es podem facilme= nte evitar o uso do scroll() ou = + do iterate() em todo c=C3=B3digo provin= do do JTA ou do CMT.) = + + + + + + + Tratamento de Exce=C3=A7=C3=A3o + + + Se a Session levantar uma exce=C3=A7=C3= =A3o (incluindo qualquer = + SQLException), voc=C3=AA deve imediatam= ente dar um rollback = + na transa=C3=A7=C3=A3o do banco, chamando Session= .close() e descartando = + a inst=C3=A2ncia da Session. Certos m= =C3=A9todos da Session = + n=C3=A3o deixar=C3=A3o a sess=C3=A3o em= um estado inconsistente. Nenhuma exce=C3=A7=C3=A3o = + lan=C3=A7ada pelo Hibernate pode ser recuperada. Certifiqu= e-se que a Session + ser=C3=A1 fechada chamando close() no b= loco finally. + + + + A exce=C3=A7=C3=A3o HibernateException,= a qual envolve a maioria dos erros = + que podem ocorrer em uma camada de persist=C3=AAncia do Hi= bernate, =C3=A9 uma exce=C3=A7=C3=A3o unchecked ( + n=C3=A3o estava em umas vers=C3=B5es mais antigas de Hiber= nate). Em nossa opini=C3=A3o, n=C3=B3s n=C3=A3o devemos + for=C3=A7ar o desenvolvedor a tratar uma exce=C3=A7=C3=A3o= irrecuper=C3=A1vel em uma camada mais baixa. = + Na maioria dos sistemas, as exce=C3=A7=C3=B5es unchecked e= fatais s=C3=A3o tratadas em um dos primeiros = + frames da pilha da chamada do m=C3=A9todo (isto =C3=A9, em= umas camadas mais elevadas) e uma mensagem = + de erro =C3=A9 apresentada ao usu=C3=A1rio da aplica=C3=A7= =C3=A3o (ou a alguma outra a=C3=A7=C3=A3o apropriada =C3=A9 feita). = + Note que Hibernate pode tamb=C3=A9m lan=C3=A7ar outras exc= e=C3=A7=C3=B5es unchecked que n=C3=A3o s=C3=A3o um = + HibernateException. Estas, tamb=C3=A9m = s=C3=A3o, irrecuper=C3=A1veis e uma a=C3=A7=C3=A3o = + apropriada deve ser tomada. + + + + O Hibernate envolve SQLExceptions lan= =C3=A7adas ao interagir com a base de dados = + em um JDBCException. Na realidade, o Hi= bernate tentar=C3=A1 converter a exce=C3=A7=C3=A3o em + em uma sub classe mais significativa da JDBCExcep= tion. A = + SQLException subjacente est=C3=A1 sempr= e dispon=C3=ADvel atrav=C3=A9s de = + JDBCException.getCause(). = + + O Hibernate converte a SQLException em = uma sub classe = + JDBCException apropriada usando SQLExceptionConverter = + associado ao SessionFactory. Por padr=C3=A3o, o S= QLExceptionConverter =C3=A9 definido = + pelo dialeto configurado; entretanto, =C3=A9 tamb=C3=A9m p= oss=C3=ADvel conectar em uma implementa=C3=A7=C3=A3o customizada + (veja o javadoc para mais detalhes da classe SQL= ExceptionConverterFactory). = + Os subtipos padr=C3=A3o de JDBCException s=C3=A3o: + + + + + + JDBCConnectionException - indic= a um erro com a comunica=C3=A7=C3=A3o subjacente de JDBC. + + + + + SQLGrammarException - indica um= problema da gram=C3=A1tica ou da sintaxe com o SQL emitido. + + + + + ConstraintViolationException - = indica algum forma de viola=C3=A7=C3=A3o de confinamento de integridade. + + + + + LockAcquisitionException - indi= ca um erro ao adquirir um n=C3=ADvel de bloqueio necess=C3=A1rio para reali= zar a opera=C3=A7=C3=A3o de requisi=C3=A7=C3=A3o. + + + + + GenericJDBCException - uma exce= =C3=A7=C3=A3o gen=C3=A9rica que n=C3=A3o cai em algumas das outras categori= as. = + + + + + + + + Timeout de Transa=C3=A7=C3=A3o + + + Uma caracter=C3=ADstica extremamente importante fornecida = por um ambiente = + gerenciado como EJB e que nunca =C3=A9 fornecido pelo c=C3= =B3digo n=C3=A3o gerenciado =C3=A9 o timeout = + de transa=C3=A7=C3=A3o. Timeouts de transa=C3=A7=C3=A3o as= seguram que nenhuma transa=C3=A7=C3=A3o possa = + reter indefinidamente recursos enquanto n=C3=A3o retorna = nenhuma resposta ao usu=C3=A1rio. + Fora de um ambiente controlado (JTA), o Hibernate n=C3=A3o= pode fornecer inteiramente = + esta funcionalidade. Entretanto, o Hibernate pode afinal c= ontrolar as opera=C3=A7=C3=B5es = + do acesso a dados, assegurando que o n=C3=ADvel de deadloc= ks e queries do banco de = + dados com imensos resultados definidos sejam limitados pel= o timeout. Em um ambiente = + gerenciado, o Hibernate pode delegar o timeout da transa= =C3=A7=C3=A3o ao JTA. Esta funcionalidade = + =C3=A9 abstra=C3=ADda pelo objeto Transaction do Hibernate. = + + = + + + + Veja que setTimeout() n=C3=A3o pode ser= chamado em um CMT bean, = + onde os timeouts das transa=C3=A7=C3=B5es devem ser defini= dos declarativamente. + + = + + = + + + + Controle de concorr=C3=AAncia otimista + + + O =C3=BAnico caminho que =C3=A9 consistente com a elevada conc= orr=C3=AAncia e escalabilidade = + =C3=A9 controle de concorr=C3=AAncia otimista com versionament= o. Checagem de vers=C3=A3o usa = + n=C3=BAmero de vers=C3=A3o, ou timestamps, para detectar confl= itos de atualiza=C3=A7=C3=B5es (e para = + impedir atualiza=C3=A7=C3=B5es perdidas). O Hibernate fornece = tr=C3=AAs caminhos poss=C3=ADveis para = + escrever aplica=C3=A7=C3=B5es que usam concorr=C3=AAncia otimi= sta. Os casos de uso que n=C3=B3s mostramos = + est=C3=A3o no contexto de conversa=C3=A7=C3=B5es longas, mas a= checagem de vers=C3=A3o tamb=C3=A9m tem o = + benef=C3=ADcio de impedir atualiza=C3=A7=C3=B5es perdidas em = =C3=BAnicas transa=C3=A7=C3=B5es. = + + + + Checagem de vers=C3=A3o da aplica=C3=A7=C3=A3o + + + Em uma implementa=C3=A7=C3=A3o sem muita ajuda do Hibernat= e, cada intera=C3=A7=C3=A3o com o banco de dados = + ocorre em uma nova Session e o desenvol= vedor =C3=A9 respons=C3=A1vel para = + recarregar todas as inst=C3=A2ncias persistentes da base d= e dados antes de manipul=C3=A1-las. = + Este caminho for=C3=A7a a aplica=C3=A7=C3=A3o a realizar s= ua pr=C3=B3pria checagem de vers=C3=A3o para assegurar = + a conversa=C3=A7=C3=A3o do isolamento da transa=C3=A7=C3= =A3o. Este caminho =C3=A9 menos eficiente em termos de = + acesso ao banco de dados. =C3=89 a caminho mais similar a = EJBs entity. = + + + + + + A propriedade version =C3=A9 mapeada us= ando <version>, = + e o Hibernate vai increment=C3=A1-lo-=C3=A1 automaticament= e durante o flush se a entidade = + estiver alterada. + + + + Claro, se voc=C3=AA se estiver operando em um ambiente de = baixa concorr=C3=AAncia de dados = + e n=C3=A3o requerer a checagem de vers=C3=A3o, voc=C3=AA p= ode usar este caminho e apenas saltar a = + checagem de vers=C3=A3o. Nesse caso, o ultimo c= ommit realizdo =C3=A9 = + a estrat=C3=A9gia padr=C3=A3o para suas conversa=C3=A7=C3= =B5es longas. Mantenha em mente que isto pode = + confundir os usu=C3=A1rios da aplica=C3=A7=C3=A3o, assim c= omo eles podem experimentar atualiza=C3=A7=C3=B5es + perdidas sem mensagens de erro ou uma possibilidade ajusta= r mudan=C3=A7as de conflito. + + + + + Claro que, checagem manual da vers=C3=A3o =C3=A9 somente p= ratic=C3=A1vel em circunst=C3=A2ncias triviais = + e n=C3=A3o para a maioria de aplica=C3=A7=C3=B5es. Freq=C3= =BCentemente, os grafos completos de objetos = + modificados t=C3=AAm que ser verificados, n=C3=A3o somente= =C3=BAnicas inst=C3=A2ncias. O Hibernate oferece = + checagem de vers=C3=A3o autom=C3=A1tica com uma S= ession estendida ou inst=C3=A2ncias = + desatachadas como o paradigma do projeto. + + + + + + Sess=C3=A3o estendida e versionamento autom=C3=A1tico</= title> + + <para> + Uma =C3=BAnica inst=C3=A2ncia de <literal>Session</literal= > e suas inst=C3=A2ncias persistentes = + s=C3=A3o usadas para a conversa=C3=A7=C3=A3o inteira, isto= =C3=A9 conhecido como = + <emphasis>session-per-conversation</emphasis>. O Hibernate= verifica vers=C3=B5es da inst=C3=A2ncia = + no momento dio flush, lan=C3=A7ando uma exce=C3=A7=C3=A3o = se a modifica=C3=A7=C3=A3o concorrente for detectada. = + At=C3=A9 o desenvolvedor pegar e tratar essa exce=C3=A7=C3= =A3o (as op=C3=A7=C3=B5es comuns s=C3=A3o a oportunidade = + para que o usu=C3=A1rio intercale as mudan=C3=A7as ou rein= icie a conversa=C3=A7=C3=A3o do neg=C3=B3cio com = + dados n=C3=A3o antigos). = + </para> + + <para> + The <literal>Session</literal> is disconnected from any un= derlying JDBC connection + when waiting for user interaction. This approach is the mo= st efficient in terms + of database access. The application need not concern itsel= f with version checking or + with reattaching detached instances, nor does it have to r= eload instances in every + database transaction. + A <literal>Session</literal> =C3=A9 desconectada de toda a= conex=C3=A3o JDBC subjacente = + enquanto espera a intera=C3=A7=C3=A3o do usu=C3=A1rio. Est= e caminho =C3=A9 a mais eficiente em termos = + de acesso a bancos de dados. A aplica=C3=A7=C3=A3o n=C3=A3= o necessita concernir-se com a checagem = + de vers=C3=A3o ou com as inst=C3=A2ncias destacadas reatad= as, nem tem que recarregar inst=C3=A2ncias = + em cada transa=C3=A7=C3=A3o. + </para> + + <programlisting><![CDATA[// foo is an instance loaded earlier = by the old session +Transaction t =3D session.beginTransaction(); // Obtain a new JDBC connect= ion, start transaction + +foo.setProperty("bar"); + +session.flush(); // Only for last transaction in conversation +t.commit(); // Also return JDBC connection +session.close(); // Only for last transaction in conversation]]></progr= amlisting> + <para> + O objeto <literal>foo</literal> sabe que <literal>Session<= /literal> j=C3=A1 foi carregada. Come=C3=A7ando = + uma nova transa=C3=A7=C3=A3o em uma sess=C3=A3o velha obt= =C3=A9m uma conex=C3=A3o nova e recome=C3=A7a a sess=C3=A3o. Commitando = + uma transa=C3=A7=C3=A3o desconecta uma sess=C3=A3o da cone= x=C3=A3o JDBC e retorna a conex=C3=A3o ao pool. Ap=C3=B3s a reconex=C3=A3o, = + for=C3=A7ar uma checagem de vers=C3=A3o em dados que voc= =C3=AA n=C3=A3o est=C3=A1 atualizando, voc=C3=AA pode chamar = + <literal>Session.lock()</literal> com o <literal>LockMode.= READ</literal> em todos os objetos = + que possam ter sido atualizados por uma outra transa=C3=A7= =C3=A3o. Voc=C3=AA n=C3=A3o necessita bloquear nenhum = + dado para atualizar. Geralmente voc=C3=AA configuraria <li= teral>FlushMode.MANUAL</literal> em uma + <literal>Session</literal> estendida, de modo que somente = o =C3=BAltimo ciclo da transa=C3=A7=C3=A3o tenha + permiss=C3=A3o de persistir todas as modifica=C3=A7=C3=B5e= s feitas nesta conversa=C3=A7=C3=A3o. Disso, somente esta =C3=BAltima = + transa=C3=A7=C3=A3o incluiria a opera=C3=A7=C3=A3o <litera= l>flush()</literal> e ent=C3=A3o chamar tamb=C3=A9m <literal>close()</liter= al> + da sess=C3=A3o para terminar a conversa=C3=A7=C3=A3o. + </para> + = + <para> + Este pattern =C3=A9 problem=C3=A1tico se a <literal>Sessio= n</literal> for demasiadamente grande para + ser armazenado durante o tempo que usu=C3=A1rio pensar, po= r exemplo um <literal>HttpSession</literal> = + estiver mantido t=C3=A3o pequeno quanto poss=C3=ADvel. Com= o o <literal>Session</literal> =C3=A9 tamb=C3=A9m cache = + de primeiro n=C3=ADvel (imperativo) e cont=C3=A9m todos os= objetos carregados, n=C3=B3s podemos provavelmente = + usar esta estrat=C3=A9gia somente para alguns ciclos de re= quisi=C3=A7=C3=A3o/resposta. Voc=C3=AA deve usar a + <literal>Session</literal> somente para uma =C3=BAnica con= versa=C3=A7=C3=A3o, porque ela logo tamb=C3=A9m = + estar=C3=A1 com dados velhos. + </para> + + <para> + (Note que vers=C3=B5es mais atuais de Hibernate requerem a= desconex=C3=A3o e o reconex=C3=A3o expl=C3=ADcitas de = + uma <literal>Session</literal>. Estes m=C3=A9todos s=C3=A3= o desatualizados, como o in=C3=ADcio e t=C3=A9rmino de = + uma transa=C3=A7=C3=A3o tem o mesmo efeito.) + </para> + + <para> + Note tamb=C3=A9m que voc=C3=AA deve manter a <literal>Sess= ion</literal> desconectada fechada = + para a camada de persist=C3=AAncia. Ou seja, use um EJB st= ateful session bean para = + prender a <literal>Session</literal> em um ambiente do tr= =C3=AAs camadas e n=C3=A3o o = + transferir =C3=A0 camada web (ou at=C3=A9 serializ=C3=A1-l= o para uma camada separada) + para armazen=C3=A1-lo no <literal>HttpSession</literal>. + + </para> + + <para> + O pattern sess=C3=A3o estendida, ou <emphasis>session-per-= conversation</emphasis>, =C3=A9 mais = + dif=C3=ADcil de implementar com gerenciamento autom=C3=A1t= ico de sess=C3=A3o atual. Voc=C3=AA precisa fornecer = + sua pr=C3=B3pria implementa=C3=A7=C3=A3o do <literal>Curre= ntSessionContext</literal> para isto + (veja o Hibernate Wiki para exemplos). + </para> + + </sect2> + + <sect2 id=3D"transactions-optimistic-detached"> + <title>Objetos destacados e versionamento autom=C3=A1tico</tit= le> + + <para> + Cada intera=C3=A7=C3=A3o com o armazenamento persistente o= corre em uma <literal>Session</literal> nova. = + Entretanto, as mesmas inst=C3=A2ncias persistentes s=C3=A3= o reusadas para cada intera=C3=A7=C3=A3o com o banco de dados. = + A aplica=C3=A7=C3=A3o manipula o estado das inst=C3=A2ncia= s desatachadas originalmente carregadas em um outro = + <literal>Session</literal> e reata-os ent=C3=A3o usando <l= iteral>Session.update()</literal>, = + <literal>Session.saveOrUpdate()</literal> ou <literal>Sess= ion.merge()</literal>. + </para> + + <programlisting><![CDATA[// foo is an instance loaded by a pre= vious Session +foo.setProperty("bar"); +session =3D factory.openSession(); +Transaction t =3D session.beginTransaction(); +session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded = already +t.commit(); +session.close();]]></programlisting> + + <para> + Outra vez, o Hibernate verificar=C3=A1 vers=C3=B5es da ins= t=C3=A2ncia durante o flush, = + lan=C3=A7ando uma exce=C3=A7=C3=A3o se ocorrer conflitos d= e atualiza=C3=A7=C3=B5es. + </para> + + <para> + Voc=C3=AA pode tamb=C3=A9m chamar o <literal>lock()</liter= al> em vez de <literal>update()</literal> = + e usar <literal>LockMode.READ</literal> (executando uma ch= ecagem de vers=C3=A3o, ignorando = + todos os caches) se voc=C3=AA estiver certo de que o objet= o n=C3=A3o foi modificado. + </para> + + </sect2> + + <sect2 id=3D"transactions-optimistic-customizing"> + <title>Versionamento autom=C3=A1tico customizado + + + Voc=C3=AA pode desabilitar o incremento da vers=C3=A3o aut= om=C3=A1tica de Hibernate para propriedades = + e cole=C3=A7=C3=B5es particulares configurando o mapeament= o do atributo optimistic-lock + para false. O Hibernate ent=C3=A3o n=C3=A3o ir=C3=A1 incre= menta vers=C3=B5es se a propriedade estiver + modificada. + + + + Os esquemas da base de dados legada s=C3=A3o freq=C3=BCent= emente est=C3=A1ticos e n=C3=A3o podem ser modificados. = + Ou outras aplica=C3=A7=C3=B5es puderam tamb=C3=A9m acessar= a mesma base de dados e n=C3=A3o sabem tratar a = + vers=C3=A3o dos n=C3=BAmeros ou timestamps. Em ambos os ca= sos, o versionamento n=C3=A3o pode confiar em uma = + coluna particular em uma tabela. Para for=C3=A7ar uma chec= agem de vers=C3=A3o sem uma vers=C3=A3o ou mapeamento + da propriedade do timestamp com uma compara=C3=A7=C3=A3o d= o estado de todos os campos em uma linha, = + configure optimistic-lock=3D"all" no ma= peamento <class>. = + Note que isto conceitualmente =C3=A9 somente feito em trab= alhos se Hibernate puder comparar o estado = + velho e novo, isto =C3=A9, se voc=C3=AA usa um =C3=BAnico = Session longo e n=C3=A3o = + session-per-request-with-detached-objects. + + + + =C3=80s vezes a modifica=C3=A7=C3=A3o concorrente pode ser= permitida t=C3=A3o longa quanto =C3=A0s mudan=C3=A7as que = + tiveram sido feitas que n=C3=A3o sobrepuseram. Se voc=C3= =AA configurar optimistic-lock=3D"dirty" + ao mapear o <class>, o Hibernate = comparar=C3=A1 somente campos = + modificados durante o flush. + + + + Em ambos os casos, com as colunas dedicadas da vers=C3=A3o= /timestamp ou com compara=C3=A7=C3=A3o do = + campo cheio/modificados, o Hibernate usa uma =C3=BAnica de= clara=C3=A7=C3=A3o UPDATE (com uma cl=C3=A1usula = + WHERE apropriada ) por entidade para executar a checagem d= a vers=C3=A3o e atualizar a informa=C3=A7=C3=A3o. = + Se voc=C3=AA usa a persist=C3=AAncia transitiva para casca= tear o reatamento das entidades associadas, = + o Hibernate pode executar atualiza=C3=A7=C3=B5es desnecess= =C3=A1rias. Isso n=C3=A3o =C3=A9 geralmente um problema, = + mas triggers on update em um banco de= dados podem ser executados = + mesmo quando nenhuma mudan=C3=A7a foi feita nas inst=C3=A2= ncias destacadas. Voc=C3=AA pode customizar = + este comportamento configurando select-before-upd= ate=3D"true" no = + mapeamento <class>, for=C3=A7and= o o Hibernate a d=C3=A1 um SELECT nas = + inst=C3=A2ncias para assegurar-se esse as mudan=C3=A7as oc= orreram realmente, antes de atualizar = + a linha. + + + + + + + + Locking pessimista + + + N=C3=A3o se pretende que os usu=C3=A1rios gastam muitas horas = se preocupando com suas estrat=C3=A9gias de = + locking. Geralmente =C3=A9 o bastante para especificar um n=C3= =ADvel de isolamento para as conex=C3=B5es = + JDBC e ent=C3=A3o deixar simplesmente o banco de dados fazer t= odo o trabalho. Entretanto, os = + usu=C3=A1rios avan=C3=A7ados podem =C3=A0s vezes desejar obter= locks pessimistas exclusivos, ou re-obter = + locks no in=C3=ADcio de uma nova transa=C3=A7=C3=A3o. = + + + + O Hibernate usar=C3=A1 sempre o mecanismo de lock da base de d= ados, nunca trava objetos = + na mem=C3=B3ria! + + + + A classe LockMode define os diferentes n=C3= =ADveis de lock que o Hibernate = + pode adquirir. Um lock =C3=A9 obtido pelos seguintes mecanismo= s: + + + + + + + LockMode.WRITE =C3=A9 adquirido aut= omaticamente quando o Hibernate atualiza = + ou insere uma linha. + + + + + LockMode.UPGRADE pode ser adquirido= explicitamente pelo usu=C3=A1rio = + usando SELECT ... FOR UPDATE em um = banco de dados que suporte = + esse sintaxe. + + + + + LockMode.UPGRADE_NOWAIT pode ser ad= quirido explicitamente pelo usu=C3=A1rio = + usando SELECT ... FOR UPDATE NOWAIT= no Oracle. + + + + + + LockMode.READ =C3=A9 adquirido auto= maticamente quando o Hibernate l=C3=AA = + dados em um n=C3=ADvel Repeatable Read ou Serializable= isolation. Pode ser readquirido = + explicitamente pelo usu=C3=A1rio. + + + + + LockMode.NONE representa a aus=C3=AAncia do= lock. Todos os objetos mudam para = + esse estado de lock no final da Transaction. Objetos associados com a sess=C3=A3o = + atrav=C3=A9s do m=C3=A9todo update() ou saveOrUpdate() tamb=C3=A9m s=C3=A3o + inicializados com esse lock mode. + + + + + + O lock obtido "explicitamente pelo usu=C3=A1rio" se d=C3=A1 em= uma das seguintes maneiras: + + + + + + Uma chamada a Session.load(), espec= ificando = + o LockMode. + + + + + Uma chamada a Session.lock(). + + + + + Uma chamada a Query.setLockMode(). + + + + + + Se uma Session.load() =C3=A9 invocada com <= literal>UPGRADE ou + UPGRADE_NOWAIT, e o objeto requisitado aind= a n=C3=A3o foi carregado = + pela sess=C3=A3o, o objeto =C3=A9 carregado usando SE= LECT ... FOR UPDATE. = + Se load() for chamado para um objeto que j= =C3=A1 foi carregado = + com um lock menos restritivo que o novo lock solicitado, o Hib= ernate invoca o = + m=C3=A9todo lock() para aquele objeto. + + + + O m=C3=A9todo Session.lock() executa uma v= erifica=C3=A7=C3=A3o no n=C3=BAmero da vers=C3=A3o = + se o modo de lock especificado for READ, UPGRADE ou + UPGRADE_NOWAIT.. (No caso do UPGRA= DE ou + UPGRADE_NOWAIT, =C3=A9 usado SELEC= T ... FOR UPDATE.) + + + + Se o banco de dados n=C3=A3o suportar o lock mode solicitado, = o Hibernate vai usar um modo = + alternativo apropriado (ao inv=C3=A9s de lan=C3=A7ar uma exce= =C3=A7=C3=A3o). Isso garante que a aplica=C3=A7=C3=A3o = + vai ser port=C3=A1vel. + + + + + + Modos de liberar a Connection + + + O comportamento legado do Hibernate (2.x) em considera=C3=A7= =C3=A3o ao gerenciamento da conex=C3=A3o = + via JDBC fez com que a Session precisasse o= bter uma conex=C3=A3o = + quando ela precisasse pela primeira vez e depois manter a cone= x=C3=A3o enquanto = + a sess=C3=A3o n=C3=A3o fosse fechada. O Hibernate 3.x introduz= a id=C3=A9ia de modos de liberar a = + sess=C3=A3o, para informar a sess=C3=A3o a forma como deve man= usear a sua conex=C3=A3o JDBC. = + Veja que essa discuss=C3=A3o s=C3=B3 =C3=A9 pertinente para co= nex=C3=B5es fornecidas com um = + ConnectionProvider configurado; conex=C3=B5= es fornecidas pelo usu=C3=A1rio = + est=C3=A3o fora do escopo dessa discuss=C3=A3o. Os diferentes = modos de libera=C3=A7=C3=A3o est=C3=A3o definidos = + pelos valores da enumera=C3=A7=C3=A3o = + org.hibernate.ConnectionReleaseMode: + = + + + + + + ON_CLOSE - essencialmente =C3=A9 o = modo legado descrito acima. A sess=C3=A3o = + do Hibernate obt=C3=AAm a conex=C3=A3o quando precisar= executar alguma opera=C3=A7=C3=A3o JDBC pela = + primeira vez e mantem enquanto a conex=C3=A3o n=C3=A3o= for fechada. + + + + + AFTER_TRANSACTION =E2=80=93 informa= que a conex=C3=A3o deve ser = + liberada ap=C3=B3s a conclus=C3=A3o de uma or= g.hibernate.Transaction. + + + + + AFTER_STATEMENT (tamb=C3=A9m conhec= ida com libera=C3=A7=C3=A3o agressiva) =E2=80=93 informa = + que a conex=C3=A3o deve ser liberada ap=C3=B3s a execu= =C3=A7=C3=A3o de cada statement. A libera=C3=A7=C3=A3o agressiva = + n=C3=A3o ocorre se o statement deixa pra tr=C3=A1s alg= um recurso aberto associado com a sess=C3=A3o = + obtida; atualmente, a =C3=BAnica situa=C3=A7=C3=A3o em= que isso =C3=A9 poss=C3=ADvel =C3=A9 com o uso de = + org.hibernate.ScrollableResults. + + + + + + O par=C3=A2metro de configura=C3=A7=C3=A3o hibernate.= connection.release_mode =C3=A9 usado = + para especificar qual modo de libera=C3=A7=C3=A3o deve ser usa= do. Op=C3=A7=C3=B5es dispon=C3=ADveis: = + + + + + + auto (padr=C3=A3o) =E2=80=93 essa = op=C3=A7=C3=A3o delega ao modo de libera=C3=A7=C3=A3o retornado pelo = + m=C3=A9todo org.hibernate.transaction.Transac= tionFactory.getDefaultReleaseMode(). = + Para JTATransactionFactory, ele retorna ConnectionRele= aseMode.AFTER_STATEMENT; para = + JDBCTransactionFactory, ele retorna ConnectionReleaseM= ode.AFTER_TRANSACTION. = + Raramente =C3=A9 uma boa id=C3=A9ia alterar padr=C3=A3= o, como frequencia ao se fazer isso temos falhas = + que parecem bugs e/ou suposi=C3=A7=C3=B5es inv=C3=A1li= das no c=C3=B3digo do usu=C3=A1rio. + + + + + on_close - indica o uso da Connecti= onReleaseMode.ON_CLOSE. Essa op=C3=A7=C3=A3o = + foi deixada para manter a compatibilidade, mas seu uso= =C3=A9 fortemente desencorajado. + + + + + after_transaction =E2=80=93 indica = o uso da ConnectionReleaseMode.AFTER_TRANSACTION. = + Essa op=C3=A7=C3=A3o nada deve ser usada com ambientes= JTA. Tamb=C3=A9m note que no caso da = + ConnectionReleaseMode.AFTER_TRANSACTION, se a sess=C3= =A3o foi colocada no modo auto-commit a = + conex=C3=A3o vai ser liberada de forma similar ao modo= AFTER_STATEMENT. + + + + + after_statement =E2=80=93 indica o = uso ConnectionReleaseMode.AFTER_STATEMENT. = + Adicionalmente, o ConnectionProvider configurado =C3=A9 consultado para = + verificar se suporta essa configura=C3=A7=C3=A3o ((supportsAggressiveRelease()). = + Se n=C3=A3o suportar, o modo de libera=C3=A7=C3=A3o = =C3=A9 redefinido como ConnectionRelease-Mode.AFTER_TRANSACTION. = + Essa configura=C3=A7=C3=A3o s=C3=B3 =C3=A9 segura em a= mbientes onde podemos readquirir a mesma conex=C3=A3o JDBC = + toda vez que o m=C3=A9todo ConnectionProvider= .getConnection() for chamado ou = + em um ambiente auto-commit onde n=C3=A3o importa se n= =C3=B3s recuperamos a mesma conex=C3=A3o. = + + + + + + + + Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tu= torial.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial= .xml 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/tutorial= .xml 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,1533 +1,1550 @@ = -=EF=BB=BF=EF=BB=BF - Introdução ao Hibernate - = - - Pref=C3=A1cio - = - - Este capítulo é um tutorial introdutório = para novos usu=C3=A1rios do Hibernate. Nós iniciaremos com uma simpl= es linha de comando em uma aplicação usando uma base de dados= em memória tornando isto um passo de f=C3=A1cil de compreender. - - - - Este tutorial é voltado para novos usu=C3=A1rios do Hib= ernate, mas requer um conhecimento de Java e SQL. Este tutorial é ba= seado no tutorial de Michael Gloegl, as bibliotecas Third Party foram nomea= das para JDK 1.4 e 5.0. Voc=C3=AA pode precisar de outras bibliotecas para = JDK 1.3. - - - - O c=C3=B3digo fonte para o tutorial est=C3=A1 inclu=C3=ADdo no= diret=C3=B3rio da distribui=C3=A7=C3=A3o = - doc/reference/tutorial/. = - - - - = - - Parte 1 =E2=80=93 A primeira aplica=C3=A7=C3=A3o Hibernate<= /title> - - <para> - Primeiro, iremos criar uma simples aplicação Hib= ernate baseada em console. Usaremos uma base de dados Java (HSQL DB), ent&#= x00E3;o não teremos que instalar nenhum servidor de base de dados. - </para> - - <para> - Vamos supor que precisemos de uma aplicação com = um banco de dados pequeno que possa armazenar e atender os eventos que quer= emos, e as informaççes sobre os hosts destes eventos. = - </para> - = - <para> - A primeira coisa que devemos fazer é configurar nosso d= iretório de desenvolvimento, = - e colocar todas as bibliotecas Java que precisamos dentro dele= . Faça o download da = - distribuição do Hibernate no site do Hibernate. = Descompacte o pacote e coloque todas = - as bibliotecas necess=C3=A1rias encontradas no diretóri= o <literal>/lib</literal>, dentro do = - diretório <literal>/lib</literal> do seu novo projeto. = Voc=C3=AA dever=C3=A1 ter algo parecido - com isso: - </para> - = - <programlisting><![CDATA[. -+lib - antlr.jar - cglib.jar - asm.jar - asm-attrs.jars - commons-collections.jar - commons-logging.jar - hibernate3.jar - jta.jar - dom4j.jar - log4j.jar ]]></programlisting> - - <para> - Esta é a configuração mínima reque= rida das bibliotecas (observe que também foi copiado = - o hibernate3.jar da pasta principal do Hibernate) para o Hiber= nate <emphasis>na hora do desenvolvimento</emphasis>. O Hibernate permite q= ue voc=C3=AA utilize mais ou menos bibliotecas. = - Veja o arquivo <literal>README.txt</literal> no diretó= rio <literal>lib/</literal> da distribuição = - do Hibernate para maiores informaççes sobre bibl= iotecas requeridas e opcionais. = - (Atualmente, a biblioteca Log4j não é requerida,= mas é preferida por muitos desenvolvedores.) - </para> - - <para> - Agora, iremos criar uma classe que representa o evento que que= remos armazenar na base de dados.. - </para> - = - <sect2 id=3D"tutorial-firstapp-firstclass" revision=3D"1"> - <title>A primeira Classe - = - - Nossa primeira classe de persist=C3=AAncia =C3=A9 uma simp= les classe JavaBean com algumas propriedades: - - - - - - Voc=C3=AA pode ver que esta classe usa o padr=C3=A3o JavaB= ean para o nomeamento convencional da propriedade getter e dos m=C3=A9todos= setter, como tamb=C3=A9m a visibilidade private dos campos. Este =C3=A9 um= padr=C3=A3o de projeto recomendado, mas n=C3=A3o requerido. O Hibernate po= de tamb=C3=A9m acessar campos diretamente, o benef=C3=ADcio para os m=C3=A9= todos de acesso =C3=A9 a robustez para o Refactoring. O construtor sem argu= mento =C3=A9 requerido para instanciar um objeto desta classe com a reflex= =C3=A3o. - - - - A propriedade id mant=C3=A9m um =C3=BA= nico valor de identifica=C3=A7=C3=A3o para um evento = - particular. Todas as classes persistentes da entidade (bem= como aquelas classes dependentes = - de menos import=C3=A2ncia) precisam de uma propriedade de = identifica=C3=A7=C3=A3o, caso n=C3=B3s queiramos usar o = - conjunto completo de caracter=C3=ADsticas do Hibernate. De= fato, a maioria das aplica=C3=A7=C3=B5es = - (esp. aplica=C3=A7=C3=B5es web) precisam destinguir os ob= jetos pelo identificador, ent=C3=A3o voc=C3=AA dever=C3=A1 = - considerar esta, uma caracter=C3=ADstica em lugar de uma l= imita=C3=A7=C3=A3o. Por=C3=A9m, n=C3=B3s normalmente n=C3=A3o = - manipulamos a identidade de um objeto, consequentemente o = m=C3=A9todo setter dever=C3=A1 ser privado. = - O Hibernate somente nomear=C3=A1 os identificadores quando= um objeto for salvo. Voc=C3=AA pode ver como = - o Hibernate pode acessar m=C3=A9todos p=C3=BAblicos, priva= dos, e protegidos, como tamb=C3=A9m campos = - (p=C3=BAblicos, privados, protegidos) diretamente. A escol= ha est=C3=A1 at=C3=A9 voc=C3=AA, e voc=C3=AA pode combinar = - isso para adaptar seu projeto de aplica=C3=A7=C3=A3o - - - - O construtor sem argumentos =C3=A9 um requerimento para to= das as classes persistentes; = - O Hibernate tem que criar para voc=C3=AA os objetos usando= Java Reflection. O construtor = - pode ser privado, por=C3=A9m, a visibilidade do pacote =C3= =A9 requerida para a procura=C3=A7=C3=A3o da = - gera=C3=A7=C3=A3o em tempo de execu=C3=A7=C3=A3o e recuper= a=C3=A7=C3=A3o eficiente dos dados sem a instrumenta=C3=A7=C3=A3o = - de bytecode = - - - - Coloque este fonte Java no diret=C3=B3rio chamado src na pasta de desenvolvimento, = - e em seu pacote correto. O diret=C3=B3rio dever=C3=A1 ser = parecido como este: - - - -+src - +events - Event.java]]> - - - No pr=C3=B3ximo passo, iremos falar sobre as classes de pe= rsist=C3=AAncia do Hibernate.. - - = - - - - O mapeamento do arquivo - - - O Hibernate precisa saber como carregar e armazenar objeto= s da classe de = - persist=C3=AAncia. Isto ser=C3=A1 onde o mapeamento do arq= uivo do Hibernate entrar=C3=A1 em = - jogo. O arquivo mapeado informa ao Hibernate, qual tabela = no banco de dados = - ele dever=C3=A1 acessar, e quais as colunas na tabela ele = dever=C3=A1 usar. - - - - A estrutura b=C3=A1sica de um arquivo de mapeamento =C3=A9= parecida com: - - - - - - -[...] -]]> - - - Note que o Hibernate DTD =C3=A9 muito sofisticado. Voc=C3= =AA pode usar isso para auto-conclus=C3=A3o = - no mapeamento XML dos elementos e atributos no seu editor = ou IDE. Voc=C3=AA tamb=C3=A9m pode = - abrir o arquivo DTD no seu editor =E2=80=93 =C3=A9 a manei= ra mais f=C3=A1cil de ter uma vis=C3=A3o geral = - de todos os elementos e atributos e dos padr=C3=B5es, como= tamb=C3=A9m alguns coment=C3=A1rios. = - Note que o Hibernate n=C3=A3o ir=C3=A1 carregar o arquivo = DTD da web, e sim do diret=C3=B3rio = - da aplica=C3=A7=C3=A3o (classpath). O arquivo DTD est=C3= =A1 inclu=C3=ADdo no hibernate3.jar como = - tamb=C3=A9m no diret=C3=B3rio src/ da d= istribui=C3=A7=C3=A3o do Hibernate. = - - - - N=C3=B3s omitiremos a declara=C3=A7=C3=A3o do DTD nos exem= plos futuros para encurtar o c=C3=B3digo. Isto, =C3=A9 claro, n=C3=A3o =C3= =A9 opcional. - - - - Entre os dois tags hibernate-mapping, i= nclua um elemento class. = - Todas as classes persistentes da entidade (novamente, pode= r=C3=A1 haver = - mais tarde, depend=C3=AAncias sobre as classes que n=C3=A3= o s=C3=A3o classes-prim=C3=A1rias = - de entidades) necessitam do tal mapeamento, para uma tabel= a na base = - de dados SQL - - - - - - - - -]]> - - - Mais adiante iremos dizer ao Hibernate como fazer para per= sistir e carregar objetos da classe = - Event da tabela EVENTS, cada instancia representada por = - uma coluna na tabela. Agora, continuaremos com o mapeament= o de uma =C3=BAnica propriedade identificadora = - para as chaves prim=C3=A1rias da tabela. Al=C3=A9m disso, = n=C3=B3s n=C3=A3o iremos se importar com esta propriedade = - identificadora, n=C3=B3s iremos configurar uma estrat=C3= =A9gia de gera=C3=A7=C3=A3o de id=E2=80=99s para uma chave prim=C3=A1ria = - de uma surrogate key: = - - - - - - - - - - -]]> - - - O elemento id =C3=A9 a declara=C3=A7=C3= =A3o da propriedade identificadora, = - o name=3D"id" declara o nome da proprie= dade Java =E2=80=93 = - o Hibernate ir=C3=A1 usar os m=C3=A9todos getter e setter = para acessar a propriedade. - O atributo da coluna informa ao Hibernate qual coluna da t= abela EVENTS n=C3=B3s = - iremos usar como chave prim=C3=A1ria. O elemento = generator especifica = - a estrat=C3=A9gia de gera=C3=A7=C3=A3o do identificador, n= este caso usaremos native, que = - escolhe a melhor estrat=C3=A9gia dependendo da base de dad= os (dialeto) configurada. = - O Hibernate suporta a base de dados gerada, globalmente = =C3=BAnica, bem como a atribui=C3=A7=C3=A3o = - aos identificadores da aplica=C3=A7=C3=A3o (ou toda estrat= =C3=A9gia escrita para uma extens=C3=A3o). - - - - Finalmente incluiremos as declara=C3=A7=C3=B5es para as pr= opriedades persistentes da classe = - no arquivo mapeado. Por default, nenhuma das propriedades = da classe =C3=A9 considerada persistente: - - = - - - - - - - - - - -]]> - = - - Da mesma maneira que com o elemento id= , o atributo name do elemento = - property informa ao Hibernate qual m=C3= =A9todo getter e setter dever=C3=A1 usar. = - Assim, neste caso, o Hibernate ir=C3=A1 procurar pelo getDate()/setDate(), = - como tamb=C3=A9m pelo getTitle()/setTitle(). - - - - Porque fazer o mapeamento da propriedade date inclu=C3=ADdo no = - atributo column, e no title n=C3=A3o fa= zer? = - Sem o atributo column o Hibernate por p= adr=C3=A3o usa o nome = - da propriedade como o nome da coluna. Isto trabalha muito = - bem para o title. Entretanto o date =C3=A9 uma palavra-chave reservada = - na maioria dos bancos de dados, assim n=C3=B3s melhoramos = o mapeamentos = - disto com um nome diferente. - - - - A pr=C3=B3xima coisa interessante =C3=A9 que mapemanto do = title = - tamb=C3=A9m falta o atributo type. O ti= po que declaramos e o uso nos = - arquivos mapeados, n=C3=A3o s=C3=A3o como voc=C3=AA p=C3= =B4de esperar, atributos de dados Java. = - Eles n=C3=A3o s=C3=A3o como os tipos de base de dados SQL. = - Esses tipos podem ser chamados de Tipos de mapea= mento Hibernate, que s=C3=A3o conversores = - que podem traduzir tipos de dados do Java para os tipos de= dados SQL e vice-versa. = - Novamente, o Hibernate ir=C3=A1 tentar determinar a conver= s=C3=A3o correta e mapear=C3=A1 o type = - pr=C3=B3prio, caso o tipo do atributo n=C3=A3o estiver pre= sente no mapeamento. = - Em alguns casos, esta detec=C3=A7=C3=A3o autom=C3=A1tica (= que usa Reflection sobre as classes Java) = - poder=C3=A1 n=C3=A3o ter padr=C3=A3o que voc=C3=AA espera = ou necessita. = - Este =C3=A9 o caso com a propriedade date. O Hibernate n=C3=A3o pode saber se a propriedade = - (que =C3=A9 do java.util.Date) pode map= ear para uma coluna do tipo date = - do SQL, timestamp, ou time . = - N=C3=B3s preservamos a informa=C3=A7=C3=A3o cheia de datas= e horas pelo mapeamento da propriedade com um conversor = - timestamp. - - - - Este arquivo de mapeamento deve ser salvo como Ev= ent.hbm.xml, = - corretamente no diret=C3=B3rio pr=C3=B3ximo ao arquivo fon= te da Classe Java Event. = - O nomeamento dos arquivos de mapeamento podem ser arbitr= =C3=A1rios, por=C3=A9m o sufixo = - hbm.xml =C3=A9 uma conven=C3=A7=C3=A3o = da comunidade dos desenvolvedores do Hibernate. = - Esta estrutura do diret=C3=B3rio deve agora se parecer com= isso: - - - -+src - +events - Event.java - Event.hbm.xml]]> - - - N=C3=B3s iremos continuar com a configura=C3=A7=C3=A3o pr= incipal do Hibernate. - - - - - - Configura=C3=A7=C3=A3o do Hibernate - - - Agora n=C3=B3s temos uma classe persistente e este arquivo= de mapeamento no lugar. = - Est=C3=A1 na hora de configurar o Hibernate. Antes de faze= rmos isso, iremos precisar de uma base de dados. = - O HSQL DB, um SQL DBMS feito em java, pode ser baixado atr= av=C3=A9s do site do HSQL DB(http://hsqldb.org/). = - Atualmente, voc=C3=AA s=C3=B3 precisa baixar o hs= qldb.jar. = - Coloque este arquivo no diret=C3=B3rio da pasta de desenvo= lvimento lib/. - - - - Crie um diret=C3=B3rio chamado data no= diret=C3=B3rio root de desenvolvimento =E2=80=93 = - Isto ser=C3=A1 onde o HSQL DB ir=C3=A1 armazenar arquivos = de dados. Agora iremos iniciar o banco de dados = - executando java -classpath ../lib/hsqldb.jar org= .hsqldb.Server neste diret=C3=B3rio de dados. = - Voc=C3=AA pode ver ele iniciando e conectando ao socket TC= P/IP, isto ser=C3=A1 onde nossa aplica=C3=A7=C3=A3o ir=C3=A1 se = - conectar depois. Se voc=C3=AA deseja iniciar uma nova base= de dados durante este tutorial, = - finalize o HSQL DB(pressionando o CTRL + C na janela), delete todos os = - arquivos no diret=C3=B3rio data/, e ini= cie o HSQL BD novamente. - - - - O Hibernate =C3=A9 uma camada na sua aplica=C3=A7=C3=A3o n= a qual se conecta com a base de dados, para isso - necessita de informa=C3=A7=C3=A3o da conex=C3=A3o. As cone= x=C3=B5es s=C3=A3o feitas atrav=C3=A9s de um pool de conex=C3=A3o JDBC, = - na qual teremos que configurar. A distribui=C3=A7=C3=A3o d= o Hibernate cont=C3=A9m diversas ferramentas de pooling = - da conex=C3=A3o JDBC de fonte aberta, mas iremos usar o po= ol de conex=C3=A3o interna para este tutorial. = - Note que voc=C3=AA tem que copiar a biblioteca necess=C3= =A1ria em seu classpath e use configura=C3=A7=C3=B5es = - diferentes para pooling de conex=C3=A3o caso voc=C3=AA des= eje utilizar um software de pooling JDBC terceirizado = - para qualidade de produ=C3=A7=C3=A3o. - - - - Para as configura=C3=A7=C3=B5es do Hibernate, n=C3=B3s pod= emos usar um arquivo simples hibernate.properties, = - um arquivo mais ligeiramente sofisticado hibernat= e.cfg.xml ou at=C3=A9 mesmo uma = - instala=C3=A7=C3=A3o program=C3=A1tica completa. A maioria= dos usu=C3=A1rios preferem utilizar o arquivo de configura=C3=A7=C3=A3o XML - - - - - - - - - - - org.hsqldb.jdbcDriver - jdbc:hsqldb:hsql://localhost - sa - - - - 1 - - - org.hibernate.dialect.HSQLDialect - - - thread - - - org.hibernate.cache.NoCach= eProvider - - - true - - - create - - - - - -]]> - - - Note que esta configura=C3=A7=C3=A3o XML usa um diferente = DTD. N=C3=B3s configuraremos = - as SessionFactory do Hibernate =E2=80= =93 uma factory global respons=C3=A1vel = - por uma base de dedados particular. Se voc=C3=AA tiver div= ersas bases de dados, = - use diversas configura=C3=A7=C3=B5es <session-= factory>, geralmente = - em diversos arquivos de configura=C3=A7=C3=A3o (para uma p= artida mais f=C3=A1cil). = - - - - As primeiras quatro propriedades do ele= mento cont=C3=A9m a configura=C3=A7=C3=A3o = - necess=C3=A1ria para a conex=C3=A3o ao JDBC. A propriedade= propriedade dialect = - do elemento especifica a variante particular do SQL que o = Hibernate gera. = - O gerenciamento autom=C3=A1tico de sess=C3=A3o do Hibernat= e para contextos de persist=C3=AAncia = - estar=C3=A1 dispon=C3=ADvel em breve. A op=C3=A7=C3=A3o hbm2ddl.auto habilita a gera=C3=A7=C3=A3o = - autom=C3=A1tica de schemas da base de dados =E2=80=93 dire= tamente na base de dados. = - Isto tamb=C3=A9m pode ser naturalmente desligado (removend= o a op=C3=A7=C3=A3o de configura=C3=A7=C3=A3o) ou redirecionando - para um arquivo com ajuda do SchemaExport nas tarefas do Ant. = - Finalmente, iremos adicionar os arquivos das classes de pe= rsist=C3=AAncia mapeadas na configura=C3=A7=C3=A3o. - - - - Copie este arquivo no diret=C3=B3rio fonte, assim isto ir= =C3=A1 terminar na raiz (root) do = - classpath. O Hibernate automaticamente procura por um arqu= ivo chamado = - hibernate.cfg.xml na raiz do classpath,= no startup. - - - - - - Construindo com o Ant - - - Nos iremos, agora, construir o tutorial com Ant. Voc=C3=AA= ira precisar o Ant instalado =E2=80=93 = - se encontra dispon=C3=ADvel na p=C3=A1gina de download do Ant. = - Como instalar o Ant, n=C3=A3o ser=C3=A1 abordado aqui. Cas= o tenha alguma d=C3=BAvida, por favor, = - v=C3=A1 ao Ant manual. - Depois que tiver instalado o Ant, podemos come=C3=A7ar a c= riar o arquivo de constru=C3=A7=C3=A3o build.xml. = - Este arquivo ser=C3=A1 chamado de build.xml e posto diretamente no diret=C3=B3rio de desenvolvimento. - - - - Um arquivo b=C3=A1sico de build, se parece com isto: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - Isto ir=C3=A1 avisar ao Ant para adicionar todos os arquiv= os no diret=C3=B3rio lib terminando com = - .jar, para o classpath usado para compi= la=C3=A7=C3=A3o. Ir=C3=A1 tamb=C3=A9m copiar todos os = - arquivos n=C3=A3o-java para o diret=C3=B3rio alvo (arquivo= s de configura=C3=A7=C3=A3o, mapeamento). Se voc=C3=AA rodar = - o ant agora, dever=C3=A1 ter esta sa=C3=ADda. = - - - ant -Buildfile: build.xml - -copy-resources: - [copy] Copying 2 files to C:\hibernateTutorial\bin - -compile: - [javac] Compiling 1 source file to C:\hibernateTutorial\bin - -BUILD SUCCESSFUL -Total time: 1 second ]]> - - - - - Startup and helpers - - - =C3=89 hora de carregar e arquivar alguns objetos Event, mas primeiro = - n=C3=B3s temos de completar o setup com algum c=C3=B3digo = de infraestrutura. Este startup = - inclui a constru=C3=A7=C3=A3o de um objeto Sessi= onFactory global e armazenar - isto em algum lugar de f=C3=A1cil acesso para o c=C3=B3dig= o da aplica=C3=A7=C3=A3o. - Uma SessionFactory pode abrir novas Session's. = - Uma Session representa uma unidade sing= le-theaded do trabalho, a = - SessionFactory =C3=A9 um objeto global = thread-safe, instanciado uma vez. - - - - Nos iremos criar uma classe de ajuda HibernateUti= l, que toma = - conta do startup e faz acesso a uma SessionFactor= y conveniente. = - Vamos dar uma olhada na implementa=C3=A7=C3=A3o: - - - - - - Esta classe n=C3=A3o s=C3=B3 produz a global Sess= ionFactory no seu static initializer - (chamado uma vez pela JVM quando a classe =C3=A9 carregada= ), mas tamb=C3=A9m esconde o fato = - de que isto usa um static singleton. Ela pode muito bem, e= nxergar a = - SessionFactory do JNDI em um applicatio= n server. - - - - Se voc=C3=AA der =C3=A0 SessionFactory = um nome, no seu arquivo de configura=C3=A7=C3=A3o. = - O Hibernate ir=C3=A1, de fato, tentar uni-lo ao JNDI depoi= s que estiver constru=C3=ADdo. = - Para evitar este completamente este c=C3=B3digo, voc=C3=AA= tamb=C3=A9m poderia usar JMX deployment = - e deixar o cont=C3=AAiner JMX capaz, instanciar e unir um = HibernateService = - no JNDI. Essas op=C3=A7=C3=B5es avan=C3=A7adas s=C3=A3o di= scutidas no documento de refer=C3=AAncia do Hibernate. - - - - Coloque o HibernateUtil.java no diret= =C3=B3rio de arquivos = - de desenvolvimento(source), em um pacote ap=C3=B3s o events: - - - -+src - +events - Event.java - Event.hbm.xml - +util - HibernateUtil.java - hibernate.cfg.xml -+data -build.xml]]> - - - Novamente, isto deve compilar sem problemas. Finalmente, n= =C3=B3s precisamos configurar = - um sistema de logging =E2=80=93 o Hibernate usa commons lo= gging e deixa voc=C3=AA escolher entre o = - Log4j e o logging do JDK 1.4 . A maioria dos desenvolvedor= es preferem o Log4j: copie = - log4j.properties da distribui=C3=A7=C3= =A3o do Hibernate (est=C3=A1 no diret=C3=B3rio = - etc/), para seu diret=C3=B3rio src, = - depois v=C3=A1 em hibernate.cfg.xml. D=C3=AA uma olhada no= exemplo de configura=C3=A7=C3=A3o e mude as - configura=C3=A7=C3=B5es se voc=C3=AA quizer ter uma sa=C3= =ADda mais detalhada. Por default, apenas as - mensagems de startup e shwwn do Hibernate =C3=A9 mostrada= no stdout. - - - - O tutorial de infra-estrutura est=C3=A1 completo - e n=C3= =B3s j=C3=A1 estamos preparados para algum = - trabalho de verdade com o Hibernate. - - - - - - Carregando e salvando objetos - - - Finalmente, n=C3=B3s podemos usar o Hibernate para carrega= r e armazenar objetos. = - N=C3=B3s escrevemos uma classe EventManager com um m=C3=A9todo main(): - - - - - - N=C3=B3s criamos um novo objeto Event, = e passamos para o Hibernate. = - O Hibernate sabe como tomar conta do SQL e executa INSERTs = - no banco de dados. Vamos dar uma olhada na Sessio= n e no = - c=C3=B3digo Transaction-handling antes = de executarmos. - - - - Um Session =C3=A9 uma unidade simples d= e trabalho. Por agora n=C3=B3s = - iremos pegar coisas simples e assumir uma granularidade de= um-pra-um entre uma = - Session do Hibernate e uma transa=C3=A7= =C3=A3o de banco de dados. = - Para proteger nosso c=C3=B3digo de um atual sistema subjac= ente de transa=C3=A7=C3=A3o (nesse = - caso puro JDBC, mas tamb=C3=A9m poderia rodar com JTA), no= s usamos a API = - Transaction, que est=C3=A1 dispon=C3=AD= vel na Session do Hibernate. - - - - O que a sessionFactory.getCurrentSession() faz? Primeiro, voc=C3=AA pode = - chamar quantas vezes e de onde quiser, uma vez voc=C3=AA r= ecebe sua SessionFactory - (f=C3=A1cil gra=C3=A7as ao HibernateUtil). O m=C3=A9todo getCurrentSession() - sempre retorna a unidade de trabalho "corrente". Lembra de= que n=C3=B3s mudamos a op=C3=A7=C3=A3o = - de configura=C3=A7=C3=A3o desse mecanismo para thread no <= literal>hibernate.cfg.xml? Daqui em - diante, o escopo da unidade de trabalho corrente =C3=A9 a = thread Java = - corrente que executa nossa aplica=C3=A7=C3=A3o. Entretanto= , esta n=C3=A3o =C3=A9 toda a verdade. Uma = - Session come=C3=A7a quando =C3=A9 prime= iramente necess=C3=A1ria, quando =C3=A9 feita a = - primeira chamada =C3=A0 getCurrentSession(). =C3=89 ent=C3=A3o limitado pelo Hibernate = - para thread corrente. Quando a transa=C3=A7=C3=A3o termina= , tanto com commit quanto rollback, = - o Hibernate tamb=C3=A9m desune a Session da thread e fecha isso pra voc=C3=AA. = - Se voc=C3=AA chamar getCurrentSession()= novamente, voc=C3=AA receber=C3=A1 uma nova = - Session e pode come=C3=A7ar uma nova un= idade de trabalho. Esse modelo de = - programa=C3=A7=C3=A3o de limite de thread threa= d-bound, =C3=A9 o modo mais popular = - de se usar o Hibernate. - - - - D=C3=AA uma olhada no par= a mais informa=C3=A7=C3=B5es a = - respeito de manipula=C3=A7=C3=A3o de transa=C3=A7=C3=A3o e = demarca=C3=A7=C3=A3o. N=C3=B3s tamb=C3=A9m pulamos qualquer = - manipula=C3=A7=C3=A3o de erro e rollback no exemplo anterio= r. - - - - Para executar esta primeira rotina, nos teremos que adicion= ar um ponto de chamada = - para o arquivo de build do Ant: - - - - - - - -]]> - - - O valor do argumento action, =C3=A9 set= ado na linha de comando quando chamando esse ponto: - - - ant run -Dactio= n=3Dstore]]> - - - Voc=C3=AA dever=C3=A1 ver, ap=C3=B3s a compila=C3=A7=C3=A3= o, o startup do Hibernate e, dependendo da sua = - configura=C3=A7=C3=A3o, muito log de sa=C3=ADda. No final = voc=C3=AA ver=C3=A1 a seguinte linha: - - - - - - Este =C3=A9 o INSERT executado pelo Hib= ernate, os pontos de interroga=C3=A7=C3=A3o = - representam par=C3=AAmetros de uni=C3=A3o do JDBC. Para ve= r os valores substitu=C3=ADdos, ou para diminuir a = - verbalidade do log, check seu llog4j.properties. - - - - Agora n=C3=B3s gostar=C3=ADamos de listar os eventos arquiva= dos, ent=C3=A3o n=C3=B3s adicionamos uma = - op=C3=A7=C3=A3o para o m=C3=A9todo main: - - - - - - Nos tamb=C3=A9m adicionamos um novo m=C3=A9todo l= istEvents(): - - - - - - O que n=C3=B3s fazemos aqui, =C3=A9 usar uma query HQL (Hi= bernate Query Language), = - para carregar todos os objetos Event e= xitentes no banco de dados. = - O Hibernate ir=C3=A1 gerar o SQL apropriado, enviar para o= banco de dados e popular objetos = - Event com os dados. Voc=C3=AA pode cria= r queries mais complexas com = - HQL, claro. - - - - Agora, para executar e testar tudo isso, siga os passos a = seguir: - - - - - - Execute ant run -Daction=3Dstore para armazenar algo no banco de dados = - e, claro, gerar o esquema do banco de dados antes = pelo hbm2ddl. - - - - - Agora desabilite hbm2ddl comentando a propriedade = no seu arquivo hibernate.cfg.xml. = - Normalmente s=C3=B3 se deixa habilitado em teste u= nit=C3=A1rios cont=C3=ADnuos, mas outra carga de hbm2ddl = - pode remover tudo que voc=C3= =AA j=C3=A1 tenha arquivado. Sa configura=C3=A7=C3=A3o = - create, atualmente s=C3=A3o tra= duzidas para "apague todas as tabelas do esquema, = - ent=C3=A3o recrie todas quando a SessionFactory es= tiver pronta". - - - - - - Se voc=C3=AA agora chamar o Ant com -Daction=3Dli= st, voc=C3=AA dever=C3=A1 ver os = - eventos que voc=C3=AA acabou de criar. Voc=C3=AA pode tamb= =C3=A9m chamar a a=C3=A7=C3=A3o store = - mais algumas vezes. = - - - - Nota: A maioria dos novos usu=C3=A1rios do Hibernate falha= nesse ponto e n=C3=B3s regularmente, vemos = - quest=C3=B5es sobre mensagens de erro de tabela = n=C3=A3o encontrada . = - Entretanto, se voc=C3=AA seguir os passos marcados acima, = voc=C3=AA n=C3=A3o ter=C3=A1 esse problema, = - com o hbm2ddl criando o esquema do banco de dados na prime= ira execu=C3=A7=C3=A3o, e restarts - subsequentes da aplica=C3=A7=C3=A3o ir=C3=A3o usar este es= quema. Se voc=C3=AA mudar o mapeamento e/ou - o esquema do banco de dados, ter=C3=A1 de re-habilitar o h= bm2ddl mais uma vez. - - - - - - - - Part 2 - Mapeando associa=C3=A7=C3=B5es - - - N=C3=B3s mapeamos uma classe de entidade de persist=C3=AAncia p= ara uma tabela. Agora vamos continuar - e adicionar algumas associa=C3=A7=C3=B5es de classe. Primeiro n= os iremos adicionar pessoas a nossa aplica=C3=A7=C3=A3o, = - e armazenar os eventos de que elas participam. - - - - Mapeando a classe Person - - - O primeiro c=C3=B3digo da classe Person= =C3=A9 simples: - - - - - - Crie um novo arquivo de mapeamento, chamado Perso= n.hbm.xml (n=C3=A3o = - esque=C3=A7a a referencia ao DTD no topo) - - - - - - - - - - - - - -]]> - - - Finalmente, adicione o novo mapeamento a configura=C3=A7= =C3=A3o do Hibernate: - - - -]]> - - - Nos iremos agora criar uma associa=C3=A7=C3=A3o entre esta= s duas entidades. Obviamente, = - pessoas (Person) podem participar de eventos, e eventos po= ssuem participantes. = - As quest=C3=B5es de design com que teremos de lidar s=C3= =A3o: direcionalidade, multiplicidade e = - comportamento de cole=C3=A7=C3=A3o. - - - - - - Uma associa=C3=A7=C3=A3o Set-based unidirectional</titl= e> - - <para> - Nos iremos adicionar uma cole=C3=A7=C3=A3o de eventos na c= lasse <literal>Person</literal>. Desse jeito = - poderemos navegar pelos eventos de uma pessoa em particula= r, sem executar uma query explicitamente =E2=80=93 = - apenas chamando <literal>aPerson.getEvents()</literal>. N= os usaremos uma cole=C3=A7=C3=A3o Java, um = - <literal>Set</literal>, porqu=C3=AA a cole=C3=A7=C3=A3o n= =C3=A3o conter=C3=A1 elementos duplicados e a ordem n=C3=A3o =C3=A9 = - relevante para n=C3=B3s. - </para> - - <para> - Vamos escrever o c=C3=B3digo para isto nas classes Java e = ent=C3=A3o mapear: - </para> - - <programlisting><![CDATA[public class Person { - - private Set events =3D new HashSet(); - - public Set getEvents() { - return events; - } - - public void setEvents(Set events) { - this.events =3D events; - } -}]]></programlisting> - - <para> - Antes de mapearmos esta associa=C3=A7=C3=A3o, pense no out= ro lado. Claramente, poder=C3=ADamos apenas fazer isto de = - forma unidirecional. Ou poder=C3=ADamos criar outra cole= =C3=A7=C3=A3o no <literal>Event</literal>, se quisermos = - ser capaz de navegar bidirecionalmente, i.e. um - <literal= >anEvent.getParticipants()</literal>. = - Isto n=C3=A3o =C3=A9 necess=C3=A1rio, de perspectiva funci= onal. Voc=C3=AA poderia sempre executar uma query explicita = - que retornasse os participantes de um evento em particular= . Esta =C3=A9 uma escolha de design que cabe = - a voc=C3=AA, mas o que =C3=A9 claro nessa discuss=C3=A3o = =C3=A9 a multiplicidade da associa=C3=A7=C3=A3o: "muitos" valores em ambos = - os lados, n=C3=B3s chamamos isto uma associa=C3=A7=C3=A3o = <emphasis>muitos-para-muitos</emphasis>. Daqui pra frente, = - nos usaremos o mapeamento muitos-para-muitos do Hibernate: - </para> - - <programlisting><![CDATA[<class name=3D"events.Person" table= =3D"PERSON"> - <id name=3D"id" column=3D"PERSON_ID"> - <generator class=3D"native"/> - </id> - <property name=3D"age"/> - <property name=3D"firstname"/> - <property name=3D"lastname"/> - - <set name=3D"events" table=3D"PERSON_EVENT"> - <key column=3D"PERSON_ID"/> - <many-to-many column=3D"EVENT_ID" class=3D"events.Event"/> - </set> - -</class>]]></programlisting> - - <para> - O Hibernate suporta todo tipo de mapeamento de cole=C3=A7= =C3=A3o , sendo um <literal><set></literal> mais comum. = - Para uma associa=C3=A7=C3=A3o muitos-para-muitos (ou relac= ionamento de entidade <emphasis>n:m</emphasis> ), = - uma tabela de associa=C3=A7=C3=A3o =C3=A9 necess=C3=A1ria.= Cada linha nessa tabela representa um link entre uma pessoa e um = - evento. O nome da tabela =C3=A9 configurado com o atributo= <literal>table</literal> do elemento = - <literal>set</literal>. O nome da coluna identificadora na= associ=C3=A7=C3=A3o, peloo lado da pessoa, = - =C3=A9 definido com o elemento <literal><key></liter= al> , o nome da coluna pelo lado dos eventos, = - e definido com o atributo <literal>column</literal> do <= literal><many-to-many></literal>. = - Voc=C3=AA tamb=C3=A9m precisa dizer para o Hibernate a cla= sse dos objetos na sua cole=C3=A7=C3=A3o (a classe do outro = - lado das cole=C3=A7=C3=B5es de refer=C3=AAncia). - </para> - - <para> - O esquema de mapeamento para o banco de dados est=C3=A1 a = seguir: - </para> - - <programlisting><![CDATA[ - _____________ __________________ - | | | | _____________ - | EVENTS | | PERSON_EVENT | | | - |_____________| |__________________| | PERSON | - | | | | |_____________| - | *EVENT_ID | <--> | *EVENT_ID | | | - | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | - | TITLE | |__________________| | AGE | - |_____________| | FIRSTNAME | - | LASTNAME | - |_____________| - ]]></programlisting> - - </sect2> - - <sect2 id=3D"tutorial-associations-working" revision=3D"1"> - <title>Trabalhando a associa=C3=A7=C3=A3o - - - Vamos trazer juntos algumas pessoas e eventos em um novo m= =C3=A9todo na classe EventManager:: - - - - - - Ap=C3=B3s carregar um Person e um Event, simplesmente = - modifique a cole=C3=A7=C3=A3o usando os m=C3=A9todos norma= is de uma cole=C3=A7=C3=A3o. Como voc=C3=AA pode ver, n=C3=A3o h=C3=A1 cham= ada expl=C3=ADcita = - para update() ou save(), o Hibernate detecta automaticamente = - que a cole=C3=A7=C3=A3o foi modificada e necessita ser atu= alizada. Isso =C3=A9 chamado de checagem = - suja autom=C3=A1tica, e voc=C3=AA tamb=C3=A9m p= ode us=C3=A1-la modificando o nome ou a data de qualquer um dos = - seus objetos. Assim que eles estiverem no estado persistent, ou seja, = - limitado por uma Session do Hibernate e= m particular (i.e. eles foram carregados ou = - salvos dentro de uma unidade de trabalho), o Hibernate mon= itora qualquer altera=C3=A7=C3=A3o e executa o SQL = - em modo de escrita em segundo plano. O processo de sincron= iza=C3=A7=C3=A3o do estado da mem=C3=B3ria com o banco de = - dados, geralmente apenas no final de uma unidade de trabal= ho, =C3=A9 chamado de flushing. = - No nosso c=C3=B3digo, a unidade de trabalho termina com o = commit da transa=C3=A7=C3=A3o do banco de dados =E2=80=93 = - como definido pela op=C3=A7=C3=A3o de configura=C3=A7=C3= =A3o da thread da classe CurrentSessionContext= . - - - - Voc=C3=AA pode tamb=C3=A9m querer carregar pessoas e event= os em diferentes unidades de trabalho. = - Ou voc=C3=AA modifica um objeto fora de uma Sessi= on, quando n=C3=A3o se encontra no = - estado persistent (se j=C3=A1 esteve neste estado anterior= mente, chamamos esse estado de = - detached). Voc=C3=AA pode at=C3=A9 me= smo modificar uma cole=C3=A7=C3=A3o quando esta = - se encontrar no estado detached. - - - - - - A chamada update cria um objeto persist= ent novamente, voc=C3=AA poderia = - dizer que ele liga o objeto a uma nova unidade de trabalho= , assim qualquer modifica=C3=A7=C3=A3o = - que voc=C3=AA fa=C3=A7a neste objeto enquanto estiver no e= stado detached pode ser salvo no banco de dados. = - Isso inclui qualquer modifica=C3=A7=C3=A3o (adi=C3=A7=C3= =A3o/exclus=C3=A3o) que voc=C3=AA fa=C3=A7a em uma cole=C3=A7=C3=A3o da ent= idade deste objeto. - - - - Bom, isso n=C3=A3o foi muito usado na nossa situa=C3=A7=C3= =A3o, por=C3=A9m, =C3=A9 um importante conceito que voc=C3=AA = - pode aplicar em seus aplicativos. Agora, complete este exe= rc=C3=ADcio adicionando uma nova a=C3=A7=C3=A3o = - ao m=C3=A9todo main( ) da classe EventManager e chame-o pela linha de comando. = - Se voc=C3=AA precisar dos identificadores de uma pessoa ou= evento =E2=80=93 o m=C3=A9todo save() = - retorna estes identificadores (voc=C3=AA poder=C3=A1 modif= icar alguns dos m=C3=A9todos anteriores para retornar aquele = - identificador): - - - - - - Este foi um exemplo de uma associa=C3=A7=C3=A3o entre duas= classes igualmente importantes, duas entidades. = - Como mencionado anteriormente, h=C3=A1 outras classes e ti= pos dentro de um modelo t=C3=ADpico, = - geralmente "menos importante". Alguns voc=C3=AA j=C3=A1 vi= u, como um int ou uma String. - N=C3=B3s chamamos essas classes de value types, e suas inst=C3=A2ncias depend - de uma entidade particular. As inst=C3=A2ncias desses tipo= s n=C3=A3o possuem sua pr=C3=B3pria identidade, nem s=C3=A3o = - compartilhados entre entidades (duas pessoas n=C3=A3o refe= renciam o mesmo objeto firstname - mesmo se elas tiverem o mesmo objeto firstname). Naturalme= nte, os value types n=C3=A3o s=C3=A3o apenas encontrados = - dentro da JDK (de fato, em um aplicativo Hibernate todas a= s classes JDK s=C3=A3o consideradas como value types), = - mas voc=C3=AA pode tamb=C3=A9m criar suas classes como, po= r exemplo, Address ou MonetaryAmount. - - - - - Voc=C3=AA tamb=C3=A9m pode criar uma cole=C3=A7=C3=A3o de = value types. Isso =C3=A9 conceitualmente muito diferente = - de uma cole=C3=A7=C3=A3o de refer=C3=AAncias para outras e= ntidades, mas em Java parece ser quase a mesma coisa. - - - - - - Cole=C3=A7=C3=A3o de valores - - - N=C3=B3s adicionamos uma cole=C3=A7=C3=A3o de objetos de t= ipo de valores =C3=A0 entidade Person. = - N=C3=B3s querermos armazenar endere=C3=A7os de e-mail, par= a isso utilizamos o tipo String, = - e a cole=C3=A7=C3=A3o novamente ser=C3=A1 um Set<= /literal>: - - - - - O mapeamento deste Set: - - - - - -]]> - - - A diferen=C3=A7a comparada com o mapeamento anterior se en= contra na parte element, = - que indica ao Hibernate que a cole=C3=A7=C3=A3o n=C3=A3o c= ont=C3=A9m refer=C3=AAncias =C3=A0 outra entidade, mas uma cole=C3=A7=C3=A3= o de = - elementos do tipo String (a tag name em= miniscula indica que se trata de um = - mapeamento do Hibernate para convers=C3=A3o de tipos). Mai= s uma vez, o atributo table = - do elemento set determina o nome da tab= ela para a cole=C3=A7=C3=A3o. O elemento = - key define o nome da coluna de chave e= strangeira na tabela de cole=C3=A7=C3=A3o. = - O atributo column dentro do elemento element define o = - nome da coluna onde os valores da String ser=C3=A3o armazenados. - - - - D=C3=AA uma olhada no esquema atualizado: - - - | *EVENT_ID | | | |____= _______________| - | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *P= ERSON_ID | - | TITLE | |__________________| | AGE | | *E= MAIL_ADDR | - |_____________| | FIRSTNAME | |____= _______________| - | LASTNAME | - |_____________| - ]]> - - - Voc=C3=AA pode observar que a chave prim=C3=A1ria da tabel= a da cole=C3=A7=C3=A3o =C3=A9 de na verdade uma chave composta, = - usando ambas colunas. Isso tamb=C3=A9m implica que cada pe= ssoa n=C3=A3o pode ter endere=C3=A7os de e-mail = - duplicados, o que =C3=A9 exatamente a sem=C3=A2ntica que p= recisamos para um set em Java. - - - - Voc=C3=AA pode agora tentar adicionar elementos a essa col= e=C3=A7=C3=A3o, do mesmo modo que fizemos = - anteriormente ligando pessoas e eventos. =C3=88 o mesmo c= =C3=B3digo em Java: - - - - - - This time we didnt' use a fetch query= to initialize the collection. - Hence, the call to its getter method will trigger an addit= ional select to initialize - it, so we can add an element to it. Monitor the SQL log an= d try to optimize this with - an eager fetch. - - - - - - Associa=C3=A7=C3=B5es bidirecionais - - - Agora iremos mapear uma associa=C3=A7=C3=A3o bidirecional = =E2=80=93 fazendo a associa=C3=A7=C3=A3o entre pessoas e = - eventos, de ambos os lados, em Java. Logicamente, o esquem= a do banco de dados n=C3=A3o muda, = - n=C3=B3s continuamos tendo multiplicidades muitos-para-mui= tos. Um banco de dados =C3=A9 mais flex=C3=ADvel do que = - uma linguagem de programa=C3=A7=C3=A3o para redes, ele n= =C3=A3o precisa de nenhuma dire=C3=A7=C3=A3o de navega=C3=A7=C3=A3o =E2=80= =93 os = - dados podem ser acessados em qualquer caminho poss=C3=ADve= l. - - - - Primeiramente, adicione uma cole=C3=A7=C3=A3o de participa= ntes =C3=A0 classe Event: - - - - - - Agora mapeie este lado da associa=C3=A7=C3=A3o em Event.hbm.xml. - - - - - -]]> - - - Como voc=C3=AA pode ver, esses =C3=A9 uma mapeamento norma= l usando set em ambos documenentos - de mapeamento. Observe que o nome das colunas em key e many-to-many - est=C3=A3o trocados em ambos os documentos de mapeamento. = A adi=C3=A7=C3=A3o mais importante feita est=C3=A1 no atributo = - inverse=3D"true" no elemento set do map= eamento da cole=C3=A7=C3=A3o da classe Event. - - - - Isso significa que o Hibernate deve pegar o outro lado =E2= =80=93 a classe Person =E2=80=93 = - quando necessitar encontrar informa=C3=A7=C3=A3o sobre a r= ela=C3=A7=C3=A3o entre as duas entidades. Isso ser=C3=A1 muito = - mais facilmente compreendido quando voc=C3=AA analisar com= o a rela=C3=A7=C3=A3o bidirecional entre as entidades =C3=A9 criada. = - - - - - - Trabalhando com links bidirecionais - - - Primeiro tenha em mente que o Hibernate n=C3=A3o afeta a s= em=C3=A2ntica normal do Java. Como n=C3=B3s criamos = - um link entre uma Person e um = Event no exemplo unidirecional? = - N=C3=B3s adicionamos uma inst=C3=A2ncia de Event<= /literal>, da cole=C3=A7=C3=A3o de refer=C3=AAncias de eventos, = - a uma inst=C3=A2ncia de Person. Ent=C3= =A3o, obviamente, se n=C3=B3s queremos que este link funcione = - bidirecionalmente, n=C3=B3s devemos fazer a mesma coisa pa= ra o outro lado =E2=80=93 adicionando uma refer=C3=AAncia de = - Person na cole=C3=A7=C3=A3o de um Event. Esse acerto de link de ambos = - os lados =C3=A9 absolutamente necess=C3=A1rio e voc=C3=AA = nunca deve esquecer de faze-lo. - - - - Muitos desenvolvedores programam de maneira defensiva e cr= iam m=C3=A9todos - gerenciador de associa=C3=A7=C3=B5es que ajusta corretamen= te ambos os lados: - - - - - - Observe que os m=C3=A9todos set e get da a cole=C3=A7=C3= =A3o est=C3=A3o protegidos =E2=80=93 isso permite que classes e = - subclasses do mesmo pacote continuem acessando os m=C3=A9t= odos, mas previne que qualquer outra classe, = - que n=C3=A3o esteja no mesmo pacote, acesse a cole=C3=A7= =C3=A3o diretamente. Voc=C3=AA provavelmente deve fazer a mesma = - coisa para a cole=C3=A7=C3=A3o do outro lado. - - - - E sobre o mapeamento do atributo inverse? Pra voc=C3=AA, e para o Java, um link bidirecional = - =C3=A9 simplesmente o fato de ajustar corretamente as refe= r=C3=AAncias de ambos os lados. O Hibernate, entretanto = - n=C3=A3o possui informa=C3=A7=C3=A3o necess=C3=A1ria para = corretamente adaptar os estados INSERT e - UPDATE do SQL, e precisa de ajuda para = manipular as propriedades das associa=C3=A7=C3=B5es = - bidirecionais. Fazer um lado da associa=C3=A7=C3=A3o com o= atributo inverse instrui o Hibernate = - para basicamente ignora-lo, considerando-o uma c= =C3=B3pia do outro lado. Isso =C3=A9 todo o = - necess=C3=A1rio para o Hibernate trabalhar com todas as po= ssibilidades quando transformando um modelo de = - navega=C3=A7=C3=A3o bidirecional em esquema de banco de da= dos do SQL. As regras que voc=C3=AA possui para lembrar s=C3=A3o = - diretas: Todas associa=C3=A7=C3=B5es bidirecionais necessi= tam que um lado possua o atributo inverse. Em uma = - associa=C3=A7=C3=A3o de um-para-muitos, o lado de "muitos"= deve conter o atributo inverse, = - j=C3=A1 em uma associa=C3=A7=C3=A3o de muitos-para-muitos = voc=C3=AA pode pegar qualquer lado, n=C3=A3o h=C3=A1 diferen=C3=A7a. = - - - - - - Agora, vamos portar este exemplo para um pequeno aplicativo pa= ra internet. - - - - - - - EventManager um aplicativo para internet - - - Um aplicativo para internet do Hibernate usa uma Sess= ion e uma Transaction = - quase do mesmo modo que um aplicativo standalone. Entretanto, = alguns patterns comuns s=C3=A3o =C3=BAteis. = - N=C3=B3s agora criaremos um EventManagerServlet. Esse servlet lista todos os eventos = - salvos no banco de dados, e cria um formul=C3=A1rio HTML para = entrada de novos eventos. - - - - Criando um servlet b=C3=A1sico - - - Crie uma nova classe no seu diret=C3=B3rio fonte, no pacot= e events: - - - - - - O servlet manuseia somente requisi=C3=A7=C3=B5es = GET do HTTP, = - portanto o m=C3=A9todo que iremos implementar =C3=A9 doGet(): - - - - - - O pattern que estamos aplicando neste c=C3=B3digo =C3=A9 c= hamado session-per-request. - Quando uma requisi=C3=A7=C3=A3o chega ao servlet, uma nova= Session do Hibernate =C3=A9 = - aberta atrav=C3=A9s da primeira chamada para getC= urrentSession() em = - SessionFactory. Ent=C3=A3o uma transa= =C3=A7=C3=A3o do banco de dados =C3=A9 inicializada - = - todo acesso a dados deve ocorrer dentro de uma transa=C3= =A7=C3=A3o, n=C3=A3o importando se o dado =C3=A9 de leitura ou escrita. - (n=C3=B3s n=C3=A3o devemos usar o modo auto-commit em apli= ca=C3=A7=C3=B5es). - - - - - Agora, as possibilidades de a=C3=A7=C3=B5es de uma requisi= =C3=A7=C3=A3o ser=C3=A3o processadas e uma resposta HTML ser=C3=A1 renderiz= ada. = - N=C3=B3s j=C3=A1 iremos chegar nesta parte. - - - - Finalmente, a unidade de trabalho termina quando o process= amento e a restitui=C3=A7=C3=A3o s=C3=A3o completados. = - Se ocorrer algum erro durante o processamento ou a restitu= i=C3=A7=C3=A3o, uma exce=C3=A7=C3=A3o ser=C3=A1 lan=C3=A7ada e a = - transa=C3=A7=C3=A3o do banco de dados encerrada. Isso comp= leta o pattern session-per-request. = - Em vez de usar c=C3=B3digo de demarca=C3=A7=C3=A3o de tran= sa=C3=A7=C3=A3o em todo servlet voc=C3=AA pode tamb=C3=A9m criar um filtro = servlet. = - D=C3=AA uma olhada no site do Hibernate e do Wiki para mai= ores informa=C3=A7=C3=B5es sobre esse pattern, = - chamado Open Session in View. - - - - - - Processando e renderizando - - - Vamos implementar o processamento da requisi=C3=A7=C3=A3o = e a restitui=C3=A7=C3=A3o da p=C3=A1gina HTML. - - -Event Manager"); - -// Handle actions -if ( "store".equals(request.getParameter("action")) ) { - - String eventTitle =3D request.getParameter("eventTitle"); - String eventDate =3D request.getParameter("eventDate"); - - if ( "".equals(eventTitle) || "".equals(eventDate) ) { - out.println("Please enter event title and date."); - } else { - createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate)); - out.println("Added event."); - } -} - -// Print page -printEventForm(out); -listEvents(out, dateFormatter); - -// Write HTML footer -out.println(""); -out.flush(); -out.close();]]> - - - O estilo de c=C3=B3digo acima, misturando linguagem HTML e= Java n=C3=A3o ser=C3=A1 funcional em um aplicativo = - mais complexo—tenha em mente que neste manual n=C3= =B3s estamos apenas ilustrando conceitos = - b=C3=A1sicos do Hibernate. O c=C3=B3digo imprime um cabe= =C3=A7alho HTML e um rodap=C3=A9. Dentro desta p=C3=A1gina, = - =C3=A9 mostrado um formul=C3=A1rio em HTML, para entrada d= e novos eventos, e uma lista de todos = - os eventos contidos no banco de dados. O primeiro m=C3=A9t= odo =C3=A9 trivial e apenas imprime = - uma p=C3=A1gina HTML: - - - Add new event:"); - out.println("
"); - out.println("Title:
"); - out.println("Date (e.g. 24.12.2009):
"); - out.println(""= ); - out.println("
"); -}]]>
- - - O m=C3=A9todo listEvents() usa a Session do Hibernate = - associada a thread atual para executar um query: - - - 0) { - out.println("

Events in database:

"); - out.println(""); - out.println(""); - out.println(""); - out.println(""); - out.println(""); - for (Iterator it =3D result.iterator(); it.hasNext();) { - Event event =3D (Event) it.next(); - out.println(""); - out.println(""); - out.println(""); - out.println(""); - } - out.println("
Event titleEvent date
" + event.getTitle() + "" + dateFormatter.format(event.getDate()) + "=
"); - } -}]]>
- - - Finalmente, a action store =C3=A9 passa= da pra o m=C3=A9todo = - createAndStoreEvent(), que tamb=C3=A9m = usa a = - Session da thread atual: - - - - - - Pronto, o servlet est=C3=A1 completo. Uma requisi=C3=A7=C3= =A3o para o servlet ser=C3=A1 processada = - em uma Session e uma Transac= tion simples. = - Como anteriormente, no aplicativo standalone, o Hibernate = pode automaticamente = - associar esses objetos a thread atual em execu=C3=A7=C3=A3= o. Isso possibilita a liberdade = - de voc=C3=AA modelar seu c=C3=B3digo e acessar o m=C3=A9to= do SessionFactory = - do jeito que achar melhor. Geralmente voc=C3=AA ir=C3=A1 u= sar um design mais sofisticado = - e mover o c=C3=B3digo de acesso a dados para dentro de obj= etos de acesso a dados = - (o patter DAO). Leia o Hibernate Wiki para maiores exemplo= s. - - -
- - - Instalando e testando - - - Para fazer o deploy desta aplica=C3=A7=C3=A3o voc=C3=AA te= m que criar um arquivo para web, um WAR. = - Adicione o alvo Ant abaixo em seu build.xml: - - - - - - - - - - -]]> - - - Esta target cria um arquivo chamado hibernate-tut= orial.war = - no diret=C3=B3rio do seu projeto. Ele empacota todas as bi= bliotecas e o arquivo de = - descri=C3=A7=C3=A3o web.xml, o qual =C3= =A9 esperado no diret=C3=B3rio base do seu projeto: - - - - - - - Event Manager - events.EventManagerServlet - - - - Event Manager - /eventmanager - -]]> - - - Antes de voc=C3=AA compilar e fazer o deploy desta aplica= =C3=A7=C3=A3o web, note que uma biblioteca = - adicional =C3=A9 requerida: jsdk.jar. E= sse =C3=A9 o Java servlet development kit, = - se voc=C3=AA n=C3=A3o possui esta biblioteca, fa=C3=A7a se= u download na p=C3=A1gina da Sun e copie-a - para seu diret=C3=B3rio de bibliotecas. Entretanto, ser=C3= =A1 usado somente para a compila=C3=A7=C3=A3o e = - exclu=C3=ADdo do pacote WAR. - - - - Para compilar e instalar execute ant war no seu diret=C3=B3rio do projeto = - e copie o arquivo hibernate-tutorial.war para o diret=C3=B3rio = - webapp do Tomcat. Se voc=C3=AA n=C3=A3o= possui o Tomcat instalado fa=C3=A7a = - o download e siga as instru=C3=A7=C3=B5es de instala=C3=A7= =C3=A3o. Voc=C3=AA n=C3=A3o precisa modificar = - nenhuma configura=C3=A7=C3=A3o do Tomcat para rodar este a= plicativo. - - - - Uma vez feito o deploy e com Tomcat rodando, acesse o apli= cativo em = - http://localhost:8080/hibernate-tutorial/eventman= ager. = - Veja o log do Tomcat para observar a inicializa=C3=A7=C3= =A3o do Hibernate quando a = - primeira requisi=C3=A7=C3=A3o chega ao servlet (o iniciali= zador est=C3=A1tico dentro de = - HibernateUtil =C3=A9 chamado) e para te= r uma depura=C3=A7=C3=A3o = - detalhada se ocorrer alguma exce=C3=A7=C3=A3o. = - - - - -
- - - Sum=C3=A1rio - - - Este manual cobriu os princ=C3=ADpios b=C3=A1sicos para cria= =C3=A7=C3=A3o de uma aplica=C3=A7=C3=A3o simples do Hibernate = - e uma pequena aplica=C3=A7=C3=A3o web. = - - - - Se voc=C3=AA j=C3=A1 se sente seguro com o Hibernate, continue= navegando na documenta=C3=A7=C3=A3o de refer=C3=AAncia = - por t=C3=B3picos que voc=C3=AA acha interessante =E2=80=93 os = t=C3=B3picos mais questionados s=C3=A3o: = - processo de transa=C3=A7=C3=A3o (), uso da API () = - e caracter=C3=ADsticas de consulta (). - - - - N=C3=A3o esque=C3=A7a de visitar o site do Hibernate para obte= r mais tutoriais especializados. - - - - -
+ + Introdução ao Hibernate + = + + Pref=C3=A1cio + = + + Este capítulo é um tutorial introdutório = para novos usu=C3=A1rios do Hibernate. Nós iniciaremos com uma simpl= es linha de comando em uma aplicação usando uma base de dados= em memória tornando isto um passo de f=C3=A1cil de compreender. + + + + Este tutorial é voltado para novos usu=C3=A1rios do Hib= ernate, mas requer um conhecimento de Java e SQL. Este tutorial é ba= seado no tutorial de Michael Gloegl, as bibliotecas Third Party foram nomea= das para JDK 1.4 e 5.0. Voc=C3=AA pode precisar de outras bibliotecas para = JDK 1.3. + + + + O c=C3=B3digo fonte para o tutorial est=C3=A1 inclu=C3=ADdo no= diret=C3=B3rio da distribui=C3=A7=C3=A3o = + doc/reference/tutorial/. = + + + + = + + Parte 1 =E2=80=93 A primeira aplica=C3=A7=C3=A3o Hibernate<= /title> + + <para> + Primeiro, iremos criar uma simples aplicação Hib= ernate baseada em console. Usaremos uma base de dados Java (HSQL DB), ent&#= x00E3;o não teremos que instalar nenhum servidor de base de dados. + </para> + + <para> + Vamos supor que precisemos de uma aplicação com = um banco de dados pequeno que possa armazenar e atender os eventos que quer= emos, e as informaççes sobre os hosts destes eventos. = + </para> + = + <para> + A primeira coisa que devemos fazer é configurar nosso d= iretório de desenvolvimento, = + e colocar todas as bibliotecas Java que precisamos dentro dele= . Faça o download da = + distribuição do Hibernate no site do Hibernate. = Descompacte o pacote e coloque todas = + as bibliotecas necess=C3=A1rias encontradas no diretóri= o <literal>/lib</literal>, dentro do = + diretório <literal>/lib</literal> do seu novo projeto. = Voc=C3=AA dever=C3=A1 ter algo parecido + com isso: + </para> + = + <programlisting><![CDATA[. ++lib + antlr.jar + cglib.jar + asm.jar + asm-attrs.jars + commons-collections.jar + commons-logging.jar + hibernate3.jar + jta.jar + dom4j.jar + log4j.jar ]]></programlisting> + + <para> + Esta é a configuração mínima reque= rida das bibliotecas (observe que também foi copiado = + o hibernate3.jar da pasta principal do Hibernate) para o Hiber= nate <emphasis>na hora do desenvolvimento</emphasis>. O Hibernate permite q= ue voc=C3=AA utilize mais ou menos bibliotecas. = + Veja o arquivo <literal>README.txt</literal> no diretó= rio <literal>lib/</literal> da distribuição = + do Hibernate para maiores informaççes sobre bibl= iotecas requeridas e opcionais. = + (Atualmente, a biblioteca Log4j não é requerida,= mas é preferida por muitos desenvolvedores.) + </para> + + <para> + Agora, iremos criar uma classe que representa o evento que que= remos armazenar na base de dados.. + </para> + = + <sect2 id=3D"tutorial-firstapp-firstclass" revision=3D"1"> + <title>A primeira Classe + = + + Nossa primeira classe de persist=C3=AAncia =C3=A9 uma simp= les classe JavaBean com algumas propriedades: + + + + + + Voc=C3=AA pode ver que esta classe usa o padr=C3=A3o JavaB= ean para o nomeamento convencional da propriedade getter e dos m=C3=A9todos= setter, como tamb=C3=A9m a visibilidade private dos campos. Este =C3=A9 um= padr=C3=A3o de projeto recomendado, mas n=C3=A3o requerido. O Hibernate po= de tamb=C3=A9m acessar campos diretamente, o benef=C3=ADcio para os m=C3=A9= todos de acesso =C3=A9 a robustez para o Refactoring. O construtor sem argu= mento =C3=A9 requerido para instanciar um objeto desta classe com a reflex= =C3=A3o. + + + + A propriedade id mant=C3=A9m um =C3=BA= nico valor de identifica=C3=A7=C3=A3o para um evento = + particular. Todas as classes persistentes da entidade (bem= como aquelas classes dependentes = + de menos import=C3=A2ncia) precisam de uma propriedade de = identifica=C3=A7=C3=A3o, caso n=C3=B3s queiramos usar o = + conjunto completo de caracter=C3=ADsticas do Hibernate. De= fato, a maioria das aplica=C3=A7=C3=B5es = + (esp. aplica=C3=A7=C3=B5es web) precisam destinguir os ob= jetos pelo identificador, ent=C3=A3o voc=C3=AA dever=C3=A1 = + considerar esta, uma caracter=C3=ADstica em lugar de uma l= imita=C3=A7=C3=A3o. Por=C3=A9m, n=C3=B3s normalmente n=C3=A3o = + manipulamos a identidade de um objeto, consequentemente o = m=C3=A9todo setter dever=C3=A1 ser privado. = + O Hibernate somente nomear=C3=A1 os identificadores quando= um objeto for salvo. Voc=C3=AA pode ver como = + o Hibernate pode acessar m=C3=A9todos p=C3=BAblicos, priva= dos, e protegidos, como tamb=C3=A9m campos = + (p=C3=BAblicos, privados, protegidos) diretamente. A escol= ha est=C3=A1 at=C3=A9 voc=C3=AA, e voc=C3=AA pode combinar = + isso para adaptar seu projeto de aplica=C3=A7=C3=A3o + + + + O construtor sem argumentos =C3=A9 um requerimento para to= das as classes persistentes; = + O Hibernate tem que criar para voc=C3=AA os objetos usando= Java Reflection. O construtor = + pode ser privado, por=C3=A9m, a visibilidade do pacote =C3= =A9 requerida para a procura=C3=A7=C3=A3o da = + gera=C3=A7=C3=A3o em tempo de execu=C3=A7=C3=A3o e recuper= a=C3=A7=C3=A3o eficiente dos dados sem a instrumenta=C3=A7=C3=A3o = + de bytecode = + + + + Coloque este fonte Java no diret=C3=B3rio chamado src na pasta de desenvolvimento, = + e em seu pacote correto. O diret=C3=B3rio dever=C3=A1 ser = parecido como este: + + + ++src + +events + Event.java]]> + + + No pr=C3=B3ximo passo, iremos falar sobre as classes de pe= rsist=C3=AAncia do Hibernate.. + + = + + + + O mapeamento do arquivo + + + O Hibernate precisa saber como carregar e armazenar objeto= s da classe de = + persist=C3=AAncia. Isto ser=C3=A1 onde o mapeamento do arq= uivo do Hibernate entrar=C3=A1 em = + jogo. O arquivo mapeado informa ao Hibernate, qual tabela = no banco de dados = + ele dever=C3=A1 acessar, e quais as colunas na tabela ele = dever=C3=A1 usar. + + + + A estrutura b=C3=A1sica de um arquivo de mapeamento =C3=A9= parecida com: + + + + + + +[...] +]]> + + + Note que o Hibernate DTD =C3=A9 muito sofisticado. Voc=C3= =AA pode usar isso para auto-conclus=C3=A3o = + no mapeamento XML dos elementos e atributos no seu editor = ou IDE. Voc=C3=AA tamb=C3=A9m pode = + abrir o arquivo DTD no seu editor =E2=80=93 =C3=A9 a manei= ra mais f=C3=A1cil de ter uma vis=C3=A3o geral = + de todos os elementos e atributos e dos padr=C3=B5es, como= tamb=C3=A9m alguns coment=C3=A1rios. = + Note que o Hibernate n=C3=A3o ir=C3=A1 carregar o arquivo = DTD da web, e sim do diret=C3=B3rio = + da aplica=C3=A7=C3=A3o (classpath). O arquivo DTD est=C3= =A1 inclu=C3=ADdo no hibernate3.jar como = + tamb=C3=A9m no diret=C3=B3rio src/ da d= istribui=C3=A7=C3=A3o do Hibernate. = + + + + N=C3=B3s omitiremos a declara=C3=A7=C3=A3o do DTD nos exem= plos futuros para encurtar o c=C3=B3digo. Isto, =C3=A9 claro, n=C3=A3o =C3= =A9 opcional. + + + + Entre os dois tags hibernate-mapping, i= nclua um elemento class. = + Todas as classes persistentes da entidade (novamente, pode= r=C3=A1 haver = + mais tarde, depend=C3=AAncias sobre as classes que n=C3=A3= o s=C3=A3o classes-prim=C3=A1rias = + de entidades) necessitam do tal mapeamento, para uma tabel= a na base = + de dados SQL + + + + + + + + +]]> + + + Mais adiante iremos dizer ao Hibernate como fazer para per= sistir e carregar objetos da classe = + Event da tabela EVENTS, cada instancia representada por = + uma coluna na tabela. Agora, continuaremos com o mapeament= o de uma =C3=BAnica propriedade identificadora = + para as chaves prim=C3=A1rias da tabela. Al=C3=A9m disso, = n=C3=B3s n=C3=A3o iremos se importar com esta propriedade = + identificadora, n=C3=B3s iremos configurar uma estrat=C3= =A9gia de gera=C3=A7=C3=A3o de id=E2=80=99s para uma chave prim=C3=A1ria = + de uma surrogate key: = + + + + + + + + + + +]]> + + + O elemento id =C3=A9 a declara=C3=A7=C3= =A3o da propriedade identificadora, = + o name=3D"id" declara o nome da proprie= dade Java =E2=80=93 = + o Hibernate ir=C3=A1 usar os m=C3=A9todos getter e setter = para acessar a propriedade. + O atributo da coluna informa ao Hibernate qual coluna da t= abela EVENTS n=C3=B3s = + iremos usar como chave prim=C3=A1ria. O elemento = generator especifica = + a estrat=C3=A9gia de gera=C3=A7=C3=A3o do identificador, n= este caso usaremos native, que = + escolhe a melhor estrat=C3=A9gia dependendo da base de dad= os (dialeto) configurada. = + O Hibernate suporta a base de dados gerada, globalmente = =C3=BAnica, bem como a atribui=C3=A7=C3=A3o = + aos identificadores da aplica=C3=A7=C3=A3o (ou toda estrat= =C3=A9gia escrita para uma extens=C3=A3o). + + + + Finalmente incluiremos as declara=C3=A7=C3=B5es para as pr= opriedades persistentes da classe = + no arquivo mapeado. Por default, nenhuma das propriedades = da classe =C3=A9 considerada persistente: + + = + + + + + + + + + + +]]> + = + + Da mesma maneira que com o elemento id= , o atributo name do elemento = + property informa ao Hibernate qual m=C3= =A9todo getter e setter dever=C3=A1 usar. = + Assim, neste caso, o Hibernate ir=C3=A1 procurar pelo getDate()/setDate(), = + como tamb=C3=A9m pelo getTitle()/setTitle(). + + + + Porque fazer o mapeamento da propriedade date inclu=C3=ADdo no = + atributo column, e no title n=C3=A3o fa= zer? = + Sem o atributo column o Hibernate por p= adr=C3=A3o usa o nome = + da propriedade como o nome da coluna. Isto trabalha muito = + bem para o title. Entretanto o date =C3=A9 uma palavra-chave reservada = + na maioria dos bancos de dados, assim n=C3=B3s melhoramos = o mapeamentos = + disto com um nome diferente. + + + + A pr=C3=B3xima coisa interessante =C3=A9 que mapemanto do = title = + tamb=C3=A9m falta o atributo type. O ti= po que declaramos e o uso nos = + arquivos mapeados, n=C3=A3o s=C3=A3o como voc=C3=AA p=C3= =B4de esperar, atributos de dados Java. = + Eles n=C3=A3o s=C3=A3o como os tipos de base de dados SQL. = + Esses tipos podem ser chamados de Tipos de mapea= mento Hibernate, que s=C3=A3o conversores = + que podem traduzir tipos de dados do Java para os tipos de= dados SQL e vice-versa. = + Novamente, o Hibernate ir=C3=A1 tentar determinar a conver= s=C3=A3o correta e mapear=C3=A1 o type = + pr=C3=B3prio, caso o tipo do atributo n=C3=A3o estiver pre= sente no mapeamento. = + Em alguns casos, esta detec=C3=A7=C3=A3o autom=C3=A1tica (= que usa Reflection sobre as classes Java) = + poder=C3=A1 n=C3=A3o ter padr=C3=A3o que voc=C3=AA espera = ou necessita. = + Este =C3=A9 o caso com a propriedade date. O Hibernate n=C3=A3o pode saber se a propriedade = + (que =C3=A9 do java.util.Date) pode map= ear para uma coluna do tipo date = + do SQL, timestamp, ou time . = + N=C3=B3s preservamos a informa=C3=A7=C3=A3o cheia de datas= e horas pelo mapeamento da propriedade com um conversor = + timestamp. + + + + Este arquivo de mapeamento deve ser salvo como Ev= ent.hbm.xml, = + corretamente no diret=C3=B3rio pr=C3=B3ximo ao arquivo fon= te da Classe Java Event. = + O nomeamento dos arquivos de mapeamento podem ser arbitr= =C3=A1rios, por=C3=A9m o sufixo = + hbm.xml =C3=A9 uma conven=C3=A7=C3=A3o = da comunidade dos desenvolvedores do Hibernate. = + Esta estrutura do diret=C3=B3rio deve agora se parecer com= isso: + + + ++src + +events + Event.java + Event.hbm.xml]]> + + + N=C3=B3s iremos continuar com a configura=C3=A7=C3=A3o pr= incipal do Hibernate. + + + + + + Configura=C3=A7=C3=A3o do Hibernate + + + Agora n=C3=B3s temos uma classe persistente e este arquivo= de mapeamento no lugar. = + Est=C3=A1 na hora de configurar o Hibernate. Antes de faze= rmos isso, iremos precisar de uma base de dados. = + O HSQL DB, um SQL DBMS feito em java, pode ser baixado atr= av=C3=A9s do site do HSQL DB(http://hsqldb.org/). = + Atualmente, voc=C3=AA s=C3=B3 precisa baixar o hs= qldb.jar. = + Coloque este arquivo no diret=C3=B3rio da pasta de desenvo= lvimento lib/. + + + + Crie um diret=C3=B3rio chamado data no= diret=C3=B3rio root de desenvolvimento =E2=80=93 = + Isto ser=C3=A1 onde o HSQL DB ir=C3=A1 armazenar arquivos = de dados. Agora iremos iniciar o banco de dados = + executando java -classpath ../lib/hsqldb.jar org= .hsqldb.Server neste diret=C3=B3rio de dados. = + Voc=C3=AA pode ver ele iniciando e conectando ao socket TC= P/IP, isto ser=C3=A1 onde nossa aplica=C3=A7=C3=A3o ir=C3=A1 se = + conectar depois. Se voc=C3=AA deseja iniciar uma nova base= de dados durante este tutorial, = + finalize o HSQL DB(pressionando o CTRL + C na janela), delete todos os = + arquivos no diret=C3=B3rio data/, e ini= cie o HSQL BD novamente. + + + + O Hibernate =C3=A9 uma camada na sua aplica=C3=A7=C3=A3o n= a qual se conecta com a base de dados, para isso + necessita de informa=C3=A7=C3=A3o da conex=C3=A3o. As cone= x=C3=B5es s=C3=A3o feitas atrav=C3=A9s de um pool de conex=C3=A3o JDBC, = + na qual teremos que configurar. A distribui=C3=A7=C3=A3o d= o Hibernate cont=C3=A9m diversas ferramentas de pooling = + da conex=C3=A3o JDBC de fonte aberta, mas iremos usar o po= ol de conex=C3=A3o interna para este tutorial. = + Note que voc=C3=AA tem que copiar a biblioteca necess=C3= =A1ria em seu classpath e use configura=C3=A7=C3=B5es = + diferentes para pooling de conex=C3=A3o caso voc=C3=AA des= eje utilizar um software de pooling JDBC terceirizado = + para qualidade de produ=C3=A7=C3=A3o. + + + + Para as configura=C3=A7=C3=B5es do Hibernate, n=C3=B3s pod= emos usar um arquivo simples hibernate.properties, = + um arquivo mais ligeiramente sofisticado hibernat= e.cfg.xml ou at=C3=A9 mesmo uma = + instala=C3=A7=C3=A3o program=C3=A1tica completa. A maioria= dos usu=C3=A1rios preferem utilizar o arquivo de configura=C3=A7=C3=A3o XML + + + + + + + + + + + org.hsqldb.jdbcDriver + jdbc:hsqldb:hsql://localhost + sa + + + + 1 + + + org.hibernate.dialect.HSQLDialect + + + thread + + + org.hibernate.cache.NoCach= eProvider + + + true + + + create + + + + + +]]> + + + Note que esta configura=C3=A7=C3=A3o XML usa um diferente = DTD. N=C3=B3s configuraremos = + as SessionFactory do Hibernate =E2=80= =93 uma factory global respons=C3=A1vel = + por uma base de dedados particular. Se voc=C3=AA tiver div= ersas bases de dados, = + use diversas configura=C3=A7=C3=B5es <session-= factory>, geralmente = + em diversos arquivos de configura=C3=A7=C3=A3o (para uma p= artida mais f=C3=A1cil). = + + + + As primeiras quatro propriedades do ele= mento cont=C3=A9m a configura=C3=A7=C3=A3o = + necess=C3=A1ria para a conex=C3=A3o ao JDBC. A propriedade= propriedade dialect = + do elemento especifica a variante particular do SQL que o = Hibernate gera. = + O gerenciamento autom=C3=A1tico de sess=C3=A3o do Hibernat= e para contextos de persist=C3=AAncia = + estar=C3=A1 dispon=C3=ADvel em breve. A op=C3=A7=C3=A3o hbm2ddl.auto habilita a gera=C3=A7=C3=A3o = + autom=C3=A1tica de schemas da base de dados =E2=80=93 dire= tamente na base de dados. = + Isto tamb=C3=A9m pode ser naturalmente desligado (removend= o a op=C3=A7=C3=A3o de configura=C3=A7=C3=A3o) ou redirecionando + para um arquivo com ajuda do SchemaExport nas tarefas do Ant. = + Finalmente, iremos adicionar os arquivos das classes de pe= rsist=C3=AAncia mapeadas na configura=C3=A7=C3=A3o. + + + + Copie este arquivo no diret=C3=B3rio fonte, assim isto ir= =C3=A1 terminar na raiz (root) do = + classpath. O Hibernate automaticamente procura por um arqu= ivo chamado = + hibernate.cfg.xml na raiz do classpath,= no startup. + + + + + + Construindo com o Ant + + + Nos iremos, agora, construir o tutorial com Ant. Voc=C3=AA= ira precisar o Ant instalado =E2=80=93 = + se encontra dispon=C3=ADvel na p=C3=A1gina de download do Ant. = + Como instalar o Ant, n=C3=A3o ser=C3=A1 abordado aqui. Cas= o tenha alguma d=C3=BAvida, por favor, = + v=C3=A1 ao Ant manual. + Depois que tiver instalado o Ant, podemos come=C3=A7ar a c= riar o arquivo de constru=C3=A7=C3=A3o build.xml. = + Este arquivo ser=C3=A1 chamado de build.xml e posto diretamente no diret=C3=B3rio de desenvolvimento. + + + + Um arquivo b=C3=A1sico de build, se parece com isto: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + Isto ir=C3=A1 avisar ao Ant para adicionar todos os arquiv= os no diret=C3=B3rio lib terminando com = + .jar, para o classpath usado para compi= la=C3=A7=C3=A3o. Ir=C3=A1 tamb=C3=A9m copiar todos os = + arquivos n=C3=A3o-java para o diret=C3=B3rio alvo (arquivo= s de configura=C3=A7=C3=A3o, mapeamento). Se voc=C3=AA rodar = + o ant agora, dever=C3=A1 ter esta sa=C3=ADda. = + + + ant +Buildfile: build.xml + +copy-resources: + [copy] Copying 2 files to C:\hibernateTutorial\bin + +compile: + [javac] Compiling 1 source file to C:\hibernateTutorial\bin + +BUILD SUCCESSFUL +Total time: 1 second ]]> + + + + + Startup and helpers + + + =C3=89 hora de carregar e arquivar alguns objetos Event, mas primeiro = + n=C3=B3s temos de completar o setup com algum c=C3=B3digo = de infraestrutura. Este startup = + inclui a constru=C3=A7=C3=A3o de um objeto Sessi= onFactory global e armazenar + isto em algum lugar de f=C3=A1cil acesso para o c=C3=B3dig= o da aplica=C3=A7=C3=A3o. + Uma SessionFactory pode abrir novas Session's. = + Uma Session representa uma unidade sing= le-theaded do trabalho, a = + SessionFactory =C3=A9 um objeto global = thread-safe, instanciado uma vez. + + + + Nos iremos criar uma classe de ajuda HibernateUti= l, que toma = + conta do startup e faz acesso a uma SessionFactor= y conveniente. = + Vamos dar uma olhada na implementa=C3=A7=C3=A3o: + + + + + + Esta classe n=C3=A3o s=C3=B3 produz a global Sess= ionFactory no seu static initializer + (chamado uma vez pela JVM quando a classe =C3=A9 carregada= ), mas tamb=C3=A9m esconde o fato = + de que isto usa um static singleton. Ela pode muito bem, e= nxergar a = + SessionFactory do JNDI em um applicatio= n server. + + + + Se voc=C3=AA der =C3=A0 SessionFactory = um nome, no seu arquivo de configura=C3=A7=C3=A3o. = + O Hibernate ir=C3=A1, de fato, tentar uni-lo ao JNDI depoi= s que estiver constru=C3=ADdo. = + Para evitar este completamente este c=C3=B3digo, voc=C3=AA= tamb=C3=A9m poderia usar JMX deployment = + e deixar o cont=C3=AAiner JMX capaz, instanciar e unir um = HibernateService = + no JNDI. Essas op=C3=A7=C3=B5es avan=C3=A7adas s=C3=A3o di= scutidas no documento de refer=C3=AAncia do Hibernate. + + + + Coloque o HibernateUtil.java no diret= =C3=B3rio de arquivos = + de desenvolvimento(source), em um pacote ap=C3=B3s o events: + + + ++src + +events + Event.java + Event.hbm.xml + +util + HibernateUtil.java + hibernate.cfg.xml ++data +build.xml]]> + + + Novamente, isto deve compilar sem problemas. Finalmente, n= =C3=B3s precisamos configurar = + um sistema de logging =E2=80=93 o Hibernate usa commons lo= gging e deixa voc=C3=AA escolher entre o = + Log4j e o logging do JDK 1.4 . A maioria dos desenvolvedor= es preferem o Log4j: copie = + log4j.properties da distribui=C3=A7=C3= =A3o do Hibernate (est=C3=A1 no diret=C3=B3rio = + etc/), para seu diret=C3=B3rio src, = + depois v=C3=A1 em hibernate.cfg.xml. D=C3=AA uma olhada no= exemplo de configura=C3=A7=C3=A3o e mude as + configura=C3=A7=C3=B5es se voc=C3=AA quizer ter uma sa=C3= =ADda mais detalhada. Por default, apenas as + mensagems de startup e shwwn do Hibernate =C3=A9 mostrada= no stdout. + + + + O tutorial de infra-estrutura est=C3=A1 completo - e n=C3= =B3s j=C3=A1 estamos preparados para algum = + trabalho de verdade com o Hibernate. + + + + + + Carregando e salvando objetos + + + Finalmente, n=C3=B3s podemos usar o Hibernate para carrega= r e armazenar objetos. = + N=C3=B3s escrevemos uma classe EventManager com um m=C3=A9todo main(): + + + + + + N=C3=B3s criamos um novo objeto Event, = e passamos para o Hibernate. = + O Hibernate sabe como tomar conta do SQL e executa INSERTs = + no banco de dados. Vamos dar uma olhada na Sessio= n e no = + c=C3=B3digo Transaction-handling antes = de executarmos. + + + + Um Session =C3=A9 uma unidade simples d= e trabalho. Por agora n=C3=B3s = + iremos pegar coisas simples e assumir uma granularidade de= um-pra-um entre uma = + Session do Hibernate e uma transa=C3=A7= =C3=A3o de banco de dados. = + Para proteger nosso c=C3=B3digo de um atual sistema subjac= ente de transa=C3=A7=C3=A3o (nesse = + caso puro JDBC, mas tamb=C3=A9m poderia rodar com JTA), no= s usamos a API = + Transaction, que est=C3=A1 dispon=C3=AD= vel na Session do Hibernate. + + + + O que a sessionFactory.getCurrentSession() faz? Primeiro, voc=C3=AA pode = + chamar quantas vezes e de onde quiser, uma vez voc=C3=AA r= ecebe sua SessionFactory + (f=C3=A1cil gra=C3=A7as ao HibernateUtil). O m=C3=A9todo getCurrentSession() + sempre retorna a unidade de trabalho "corrente". Lembra de= que n=C3=B3s mudamos a op=C3=A7=C3=A3o = + de configura=C3=A7=C3=A3o desse mecanismo para thread no <= literal>hibernate.cfg.xml? Daqui em + diante, o escopo da unidade de trabalho corrente =C3=A9 a = thread Java = + corrente que executa nossa aplica=C3=A7=C3=A3o. Entretanto= , esta n=C3=A3o =C3=A9 toda a verdade. Uma = + + = + + Session come=C3=A7a quando =C3=A9 primeiramente neces= s=C3=A1ria, quando =C3=A9 feita a = + primeira chamada =C3=A0 getCurrentSession(). =C3=89 ent=C3=A3o limitado pelo Hibernate = + para thread corrente. Quando a transa=C3=A7=C3=A3o termina= , tanto com commit quanto rollback, = + o Hibernate tamb=C3=A9m desune a Session da thread e fecha isso pra voc=C3=AA. = + Se voc=C3=AA chamar getCurrentSession()= novamente, voc=C3=AA receber=C3=A1 uma nova = + Session e pode come=C3=A7ar uma nova un= idade de trabalho. Esse modelo de = + programa=C3=A7=C3=A3o de limite de thread threa= d-bound, =C3=A9 o modo mais popular = + de se usar o Hibernate. + + + Related to the unit of work scope, should the Hibernate Sess= ion be used to + execute one or several database operations? The above example uses on= e Session + for one operation. This is pure coincidence, the example is just not = complex enough to show any + other approach. The scope of a Hibernate Session i= s flexible but you should + never design your application to use a new Hibernate Session= for + every database operation. So even if you see it = a few more times in + the following (very trivial) examples, consider session-per= -operation + an anti-pattern. A real (web) application is shown later in this tuto= rial. + + + D=C3=AA uma olhada no par= a mais informa=C3=A7=C3=B5es a = + respeito de manipula=C3=A7=C3=A3o de transa=C3=A7=C3=A3o e = demarca=C3=A7=C3=A3o. N=C3=B3s tamb=C3=A9m pulamos qualquer = + manipula=C3=A7=C3=A3o de erro e rollback no exemplo anterio= r. + + + + Para executar esta primeira rotina, nos teremos que adicion= ar um ponto de chamada = + para o arquivo de build do Ant: + + + + + + + +]]> + + + O valor do argumento action, =C3=A9 set= ado na linha de comando quando chamando esse ponto: + + + ant run -Dactio= n=3Dstore]]> + + + Voc=C3=AA dever=C3=A1 ver, ap=C3=B3s a compila=C3=A7=C3=A3= o, o startup do Hibernate e, dependendo da sua = + configura=C3=A7=C3=A3o, muito log de sa=C3=ADda. No final = voc=C3=AA ver=C3=A1 a seguinte linha: + + + + + + Este =C3=A9 o INSERT executado pelo Hib= ernate, os pontos de interroga=C3=A7=C3=A3o = + representam par=C3=AAmetros de uni=C3=A3o do JDBC. Para ve= r os valores substitu=C3=ADdos, ou para diminuir a = + verbalidade do log, check seu llog4j.properties. + + + + Agora n=C3=B3s gostar=C3=ADamos de listar os eventos arquiva= dos, ent=C3=A3o n=C3=B3s adicionamos uma = + op=C3=A7=C3=A3o para o m=C3=A9todo main: + + + + + + Nos tamb=C3=A9m adicionamos um novo m=C3=A9todo l= istEvents(): + + + + + + O que n=C3=B3s fazemos aqui, =C3=A9 usar uma query HQL (Hi= bernate Query Language), = + para carregar todos os objetos Event e= xitentes no banco de dados. = + O Hibernate ir=C3=A1 gerar o SQL apropriado, enviar para o= banco de dados e popular objetos = + Event com os dados. Voc=C3=AA pode cria= r queries mais complexas com = + HQL, claro. + + + + Agora, para executar e testar tudo isso, siga os passos a = seguir: + + + + + + Execute ant run -Daction=3Dstore para armazenar algo no banco de dados = + e, claro, gerar o esquema do banco de dados antes = pelo hbm2ddl. + + + + + Agora desabilite hbm2ddl comentando a propriedade = no seu arquivo hibernate.cfg.xml. = + Normalmente s=C3=B3 se deixa habilitado em teste u= nit=C3=A1rios cont=C3=ADnuos, mas outra carga de hbm2ddl = + pode remover tudo que voc=C3= =AA j=C3=A1 tenha arquivado. Sa configura=C3=A7=C3=A3o = + create, atualmente s=C3=A3o tra= duzidas para "apague todas as tabelas do esquema, = + ent=C3=A3o recrie todas quando a SessionFactory es= tiver pronta". + + + + + + Se voc=C3=AA agora chamar o Ant com -Daction=3Dli= st, voc=C3=AA dever=C3=A1 ver os = + eventos que voc=C3=AA acabou de criar. Voc=C3=AA pode tamb= =C3=A9m chamar a a=C3=A7=C3=A3o store = + mais algumas vezes. = + + + + Nota: A maioria dos novos usu=C3=A1rios do Hibernate falha= nesse ponto e n=C3=B3s regularmente, vemos = + quest=C3=B5es sobre mensagens de erro de tabela = n=C3=A3o encontrada . = + Entretanto, se voc=C3=AA seguir os passos marcados acima, = voc=C3=AA n=C3=A3o ter=C3=A1 esse problema, = + com o hbm2ddl criando o esquema do banco de dados na prime= ira execu=C3=A7=C3=A3o, e restarts + subsequentes da aplica=C3=A7=C3=A3o ir=C3=A3o usar este es= quema. Se voc=C3=AA mudar o mapeamento e/ou + o esquema do banco de dados, ter=C3=A1 de re-habilitar o h= bm2ddl mais uma vez. + + + + + + + + Part 2 - Mapeando associa=C3=A7=C3=B5es + + + N=C3=B3s mapeamos uma classe de entidade de persist=C3=AAncia p= ara uma tabela. Agora vamos continuar + e adicionar algumas associa=C3=A7=C3=B5es de classe. Primeiro n= os iremos adicionar pessoas a nossa aplica=C3=A7=C3=A3o, = + e armazenar os eventos de que elas participam. + + + + Mapeando a classe Person + + + O primeiro c=C3=B3digo da classe Person= =C3=A9 simples: + + + + + + Crie um novo arquivo de mapeamento, chamado Perso= n.hbm.xml (n=C3=A3o = + esque=C3=A7a a referencia ao DTD no topo) + + + + + + + + + + + + + +]]> + + + Finalmente, adicione o novo mapeamento a configura=C3=A7= =C3=A3o do Hibernate: + + + +]]> + + + Nos iremos agora criar uma associa=C3=A7=C3=A3o entre esta= s duas entidades. Obviamente, = + pessoas (Person) podem participar de eventos, e eventos po= ssuem participantes. = + As quest=C3=B5es de design com que teremos de lidar s=C3= =A3o: direcionalidade, multiplicidade e = + comportamento de cole=C3=A7=C3=A3o. + + + + + + Uma associa=C3=A7=C3=A3o Set-based unidirectional</titl= e> + + <para> + Nos iremos adicionar uma cole=C3=A7=C3=A3o de eventos na c= lasse <literal>Person</literal>. Desse jeito = + poderemos navegar pelos eventos de uma pessoa em particula= r, sem executar uma query explicitamente =E2=80=93 = + apenas chamando <literal>aPerson.getEvents()</literal>. N= os usaremos uma cole=C3=A7=C3=A3o Java, um = + <literal>Set</literal>, porqu=C3=AA a cole=C3=A7=C3=A3o n= =C3=A3o conter=C3=A1 elementos duplicados e a ordem n=C3=A3o =C3=A9 = + relevante para n=C3=B3s. + </para> + + <para> + Vamos escrever o c=C3=B3digo para isto nas classes Java e = ent=C3=A3o mapear: + </para> + + <programlisting><![CDATA[public class Person { + + private Set events =3D new HashSet(); + + public Set getEvents() { + return events; + } + + public void setEvents(Set events) { + this.events =3D events; + } +}]]></programlisting> + + <para> + Antes de mapearmos esta associa=C3=A7=C3=A3o, pense no out= ro lado. Claramente, poder=C3=ADamos apenas fazer isto de = + forma unidirecional. Ou poder=C3=ADamos criar outra cole= =C3=A7=C3=A3o no <literal>Event</literal>, se quisermos = + ser capaz de navegar bidirecionalmente, i.e. um - <literal= >anEvent.getParticipants()</literal>. = + Isto n=C3=A3o =C3=A9 necess=C3=A1rio, de perspectiva funci= onal. Voc=C3=AA poderia sempre executar uma query explicita = + que retornasse os participantes de um evento em particular= . Esta =C3=A9 uma escolha de design que cabe = + a voc=C3=AA, mas o que =C3=A9 claro nessa discuss=C3=A3o = =C3=A9 a multiplicidade da associa=C3=A7=C3=A3o: "muitos" valores em ambos = + os lados, n=C3=B3s chamamos isto uma associa=C3=A7=C3=A3o = <emphasis>muitos-para-muitos</emphasis>. Daqui pra frente, = + nos usaremos o mapeamento muitos-para-muitos do Hibernate: + </para> + + <programlisting><![CDATA[<class name=3D"events.Person" table= =3D"PERSON"> + <id name=3D"id" column=3D"PERSON_ID"> + <generator class=3D"native"/> + </id> + <property name=3D"age"/> + <property name=3D"firstname"/> + <property name=3D"lastname"/> + + <set name=3D"events" table=3D"PERSON_EVENT"> + <key column=3D"PERSON_ID"/> + <many-to-many column=3D"EVENT_ID" class=3D"events.Event"/> + </set> + +</class>]]></programlisting> + + <para> + O Hibernate suporta todo tipo de mapeamento de cole=C3=A7= =C3=A3o , sendo um <literal><set></literal> mais comum. = + Para uma associa=C3=A7=C3=A3o muitos-para-muitos (ou relac= ionamento de entidade <emphasis>n:m</emphasis> ), = + uma tabela de associa=C3=A7=C3=A3o =C3=A9 necess=C3=A1ria.= Cada linha nessa tabela representa um link entre uma pessoa e um = + evento. O nome da tabela =C3=A9 configurado com o atributo= <literal>table</literal> do elemento = + <literal>set</literal>. O nome da coluna identificadora na= associ=C3=A7=C3=A3o, peloo lado da pessoa, = + =C3=A9 definido com o elemento <literal><key></liter= al> , o nome da coluna pelo lado dos eventos, = + e definido com o atributo <literal>column</literal> do <= literal><many-to-many></literal>. = + Voc=C3=AA tamb=C3=A9m precisa dizer para o Hibernate a cla= sse dos objetos na sua cole=C3=A7=C3=A3o (a classe do outro = + lado das cole=C3=A7=C3=B5es de refer=C3=AAncia). + </para> + + <para> + O esquema de mapeamento para o banco de dados est=C3=A1 a = seguir: + </para> + + <programlisting><![CDATA[ + _____________ __________________ + | | | | _____________ + | EVENTS | | PERSON_EVENT | | | + |_____________| |__________________| | PERSON | + | | | | |_____________| + | *EVENT_ID | <--> | *EVENT_ID | | | + | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | + | TITLE | |__________________| | AGE | + |_____________| | FIRSTNAME | + | LASTNAME | + |_____________| + ]]></programlisting> + + </sect2> + + <sect2 id=3D"tutorial-associations-working" revision=3D"1"> + <title>Trabalhando a associa=C3=A7=C3=A3o + + + Vamos trazer juntos algumas pessoas e eventos em um novo m= =C3=A9todo na classe EventManager:: + + + + + + Ap=C3=B3s carregar um Person e um Event, simplesmente = + modifique a cole=C3=A7=C3=A3o usando os m=C3=A9todos norma= is de uma cole=C3=A7=C3=A3o. Como voc=C3=AA pode ver, n=C3=A3o h=C3=A1 cham= ada expl=C3=ADcita = + para update() ou save(), o Hibernate detecta automaticamente = + que a cole=C3=A7=C3=A3o foi modificada e necessita ser atu= alizada. Isso =C3=A9 chamado de checagem = + suja autom=C3=A1tica, e voc=C3=AA tamb=C3=A9m p= ode us=C3=A1-la modificando o nome ou a data de qualquer um dos = + seus objetos. Assim que eles estiverem no estado persistent, ou seja, = + limitado por uma Session do Hibernate e= m particular (i.e. eles foram carregados ou = + salvos dentro de uma unidade de trabalho), o Hibernate mon= itora qualquer altera=C3=A7=C3=A3o e executa o SQL = + em modo de escrita em segundo plano. O processo de sincron= iza=C3=A7=C3=A3o do estado da mem=C3=B3ria com o banco de = + dados, geralmente apenas no final de uma unidade de trabal= ho, =C3=A9 chamado de flushing. = + No nosso c=C3=B3digo, a unidade de trabalho termina com o = commit da transa=C3=A7=C3=A3o do banco de dados =E2=80=93 = + como definido pela op=C3=A7=C3=A3o de configura=C3=A7=C3= =A3o da thread da classe CurrentSessionContext= . + + + + Voc=C3=AA pode tamb=C3=A9m querer carregar pessoas e event= os em diferentes unidades de trabalho. = + Ou voc=C3=AA modifica um objeto fora de uma Sessi= on, quando n=C3=A3o se encontra no = + estado persistent (se j=C3=A1 esteve neste estado anterior= mente, chamamos esse estado de = + detached). Voc=C3=AA pode at=C3=A9 me= smo modificar uma cole=C3=A7=C3=A3o quando esta = + se encontrar no estado detached. + + + + + + A chamada update cria um objeto persist= ent novamente, voc=C3=AA poderia = + dizer que ele liga o objeto a uma nova unidade de trabalho= , assim qualquer modifica=C3=A7=C3=A3o = + que voc=C3=AA fa=C3=A7a neste objeto enquanto estiver no e= stado detached pode ser salvo no banco de dados. = + Isso inclui qualquer modifica=C3=A7=C3=A3o (adi=C3=A7=C3= =A3o/exclus=C3=A3o) que voc=C3=AA fa=C3=A7a em uma cole=C3=A7=C3=A3o da ent= idade deste objeto. + + + + Bom, isso n=C3=A3o foi muito usado na nossa situa=C3=A7=C3= =A3o, por=C3=A9m, =C3=A9 um importante conceito que voc=C3=AA = + pode aplicar em seus aplicativos. Agora, complete este exe= rc=C3=ADcio adicionando uma nova a=C3=A7=C3=A3o = + ao m=C3=A9todo main( ) da classe EventManager e chame-o pela linha de comando. = + Se voc=C3=AA precisar dos identificadores de uma pessoa ou= evento =E2=80=93 o m=C3=A9todo save() = + retorna estes identificadores (voc=C3=AA poder=C3=A1 modif= icar alguns dos m=C3=A9todos anteriores para retornar aquele = + identificador): + + + + + + Este foi um exemplo de uma associa=C3=A7=C3=A3o entre duas= classes igualmente importantes, duas entidades. = + Como mencionado anteriormente, h=C3=A1 outras classes e ti= pos dentro de um modelo t=C3=ADpico, = + geralmente "menos importante". Alguns voc=C3=AA j=C3=A1 vi= u, como um int ou uma String. + N=C3=B3s chamamos essas classes de value types, e suas inst=C3=A2ncias depend + de uma entidade particular. As inst=C3=A2ncias desses tipo= s n=C3=A3o possuem sua pr=C3=B3pria identidade, nem s=C3=A3o = + compartilhados entre entidades (duas pessoas n=C3=A3o refe= renciam o mesmo objeto firstname + mesmo se elas tiverem o mesmo objeto firstname). Naturalme= nte, os value types n=C3=A3o s=C3=A3o apenas encontrados = + dentro da JDK (de fato, em um aplicativo Hibernate todas a= s classes JDK s=C3=A3o consideradas como value types), = + mas voc=C3=AA pode tamb=C3=A9m criar suas classes como, po= r exemplo, Address ou MonetaryAmount. + + + + + Voc=C3=AA tamb=C3=A9m pode criar uma cole=C3=A7=C3=A3o de = value types. Isso =C3=A9 conceitualmente muito diferente = + de uma cole=C3=A7=C3=A3o de refer=C3=AAncias para outras e= ntidades, mas em Java parece ser quase a mesma coisa. + + + + + + Cole=C3=A7=C3=A3o de valores + + + N=C3=B3s adicionamos uma cole=C3=A7=C3=A3o de objetos de t= ipo de valores =C3=A0 entidade Person. = + N=C3=B3s querermos armazenar endere=C3=A7os de e-mail, par= a isso utilizamos o tipo String, = + e a cole=C3=A7=C3=A3o novamente ser=C3=A1 um Set<= /literal>: + + + + + O mapeamento deste Set: + + + + + +]]> + + + A diferen=C3=A7a comparada com o mapeamento anterior se en= contra na parte element, = + que indica ao Hibernate que a cole=C3=A7=C3=A3o n=C3=A3o c= ont=C3=A9m refer=C3=AAncias =C3=A0 outra entidade, mas uma cole=C3=A7=C3=A3= o de = + elementos do tipo String (a tag name em= miniscula indica que se trata de um = + mapeamento do Hibernate para convers=C3=A3o de tipos). Mai= s uma vez, o atributo table = + do elemento set determina o nome da tab= ela para a cole=C3=A7=C3=A3o. O elemento = + key define o nome da coluna de chave e= strangeira na tabela de cole=C3=A7=C3=A3o. = + O atributo column dentro do elemento element define o = + nome da coluna onde os valores da String ser=C3=A3o armazenados. + + + + D=C3=AA uma olhada no esquema atualizado: + + + | *EVENT_ID | | | |____= _______________| + | EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID | <--> | *P= ERSON_ID | + | TITLE | |__________________| | AGE | | *E= MAIL_ADDR | + |_____________| | FIRSTNAME | |____= _______________| + | LASTNAME | + |_____________| + ]]> + + + Voc=C3=AA pode observar que a chave prim=C3=A1ria da tabel= a da cole=C3=A7=C3=A3o =C3=A9 de na verdade uma chave composta, = + usando ambas colunas. Isso tamb=C3=A9m implica que cada pe= ssoa n=C3=A3o pode ter endere=C3=A7os de e-mail = + duplicados, o que =C3=A9 exatamente a sem=C3=A2ntica que p= recisamos para um set em Java. + + + + Voc=C3=AA pode agora tentar adicionar elementos a essa col= e=C3=A7=C3=A3o, do mesmo modo que fizemos = + anteriormente ligando pessoas e eventos. =C3=88 o mesmo c= =C3=B3digo em Java: + + + + + + This time we didnt' use a fetch query= to initialize the collection. + Hence, the call to its getter method will trigger an addit= ional select to initialize + it, so we can add an element to it. Monitor the SQL log an= d try to optimize this with + an eager fetch. + + + + + + Associa=C3=A7=C3=B5es bidirecionais + + + Agora iremos mapear uma associa=C3=A7=C3=A3o bidirecional = =E2=80=93 fazendo a associa=C3=A7=C3=A3o entre pessoas e = + eventos, de ambos os lados, em Java. Logicamente, o esquem= a do banco de dados n=C3=A3o muda, = + n=C3=B3s continuamos tendo multiplicidades muitos-para-mui= tos. Um banco de dados =C3=A9 mais flex=C3=ADvel do que = + uma linguagem de programa=C3=A7=C3=A3o para redes, ele n= =C3=A3o precisa de nenhuma dire=C3=A7=C3=A3o de navega=C3=A7=C3=A3o =E2=80= =93 os = + dados podem ser acessados em qualquer caminho poss=C3=ADve= l. + + + + Primeiramente, adicione uma cole=C3=A7=C3=A3o de participa= ntes =C3=A0 classe Event: + + + + + + Agora mapeie este lado da associa=C3=A7=C3=A3o em Event.hbm.xml. + + + + + +]]> + + + Como voc=C3=AA pode ver, esses =C3=A9 uma mapeamento norma= l usando set em ambos documenentos + de mapeamento. Observe que o nome das colunas em key e many-to-many + est=C3=A3o trocados em ambos os documentos de mapeamento. = A adi=C3=A7=C3=A3o mais importante feita est=C3=A1 no atributo = + inverse=3D"true" no elemento set do map= eamento da cole=C3=A7=C3=A3o da classe Event. + + + + Isso significa que o Hibernate deve pegar o outro lado =E2= =80=93 a classe Person =E2=80=93 = + quando necessitar encontrar informa=C3=A7=C3=A3o sobre a r= ela=C3=A7=C3=A3o entre as duas entidades. Isso ser=C3=A1 muito = + mais facilmente compreendido quando voc=C3=AA analisar com= o a rela=C3=A7=C3=A3o bidirecional entre as entidades =C3=A9 criada. = + + + + + + Trabalhando com links bidirecionais + + + Primeiro tenha em mente que o Hibernate n=C3=A3o afeta a s= em=C3=A2ntica normal do Java. Como n=C3=B3s criamos = + um link entre uma Person e um = Event no exemplo unidirecional? = + N=C3=B3s adicionamos uma inst=C3=A2ncia de Event<= /literal>, da cole=C3=A7=C3=A3o de refer=C3=AAncias de eventos, = + a uma inst=C3=A2ncia de Person. Ent=C3= =A3o, obviamente, se n=C3=B3s queremos que este link funcione = + bidirecionalmente, n=C3=B3s devemos fazer a mesma coisa pa= ra o outro lado =E2=80=93 adicionando uma refer=C3=AAncia de = + Person na cole=C3=A7=C3=A3o de um Event. Esse acerto de link de ambos = + os lados =C3=A9 absolutamente necess=C3=A1rio e voc=C3=AA = nunca deve esquecer de faze-lo. + + + + Muitos desenvolvedores programam de maneira defensiva e cr= iam m=C3=A9todos + gerenciador de associa=C3=A7=C3=B5es que ajusta corretamen= te ambos os lados: + + + + + + Observe que os m=C3=A9todos set e get da a cole=C3=A7=C3= =A3o est=C3=A3o protegidos =E2=80=93 isso permite que classes e = + subclasses do mesmo pacote continuem acessando os m=C3=A9t= odos, mas previne que qualquer outra classe, = + que n=C3=A3o esteja no mesmo pacote, acesse a cole=C3=A7= =C3=A3o diretamente. Voc=C3=AA provavelmente deve fazer a mesma = + coisa para a cole=C3=A7=C3=A3o do outro lado. + + + + E sobre o mapeamento do atributo inverse? Pra voc=C3=AA, e para o Java, um link bidirecional = + =C3=A9 simplesmente o fato de ajustar corretamente as refe= r=C3=AAncias de ambos os lados. O Hibernate, entretanto = + n=C3=A3o possui informa=C3=A7=C3=A3o necess=C3=A1ria para = corretamente adaptar os estados INSERT e + UPDATE do SQL, e precisa de ajuda para = manipular as propriedades das associa=C3=A7=C3=B5es = + bidirecionais. Fazer um lado da associa=C3=A7=C3=A3o com o= atributo inverse instrui o Hibernate = + para basicamente ignora-lo, considerando-o uma c= =C3=B3pia do outro lado. Isso =C3=A9 todo o = + necess=C3=A1rio para o Hibernate trabalhar com todas as po= ssibilidades quando transformando um modelo de = + navega=C3=A7=C3=A3o bidirecional em esquema de banco de da= dos do SQL. As regras que voc=C3=AA possui para lembrar s=C3=A3o = + diretas: Todas associa=C3=A7=C3=B5es bidirecionais necessi= tam que um lado possua o atributo inverse. Em uma = + associa=C3=A7=C3=A3o de um-para-muitos, o lado de "muitos"= deve conter o atributo inverse, = + j=C3=A1 em uma associa=C3=A7=C3=A3o de muitos-para-muitos = voc=C3=AA pode pegar qualquer lado, n=C3=A3o h=C3=A1 diferen=C3=A7a. = + + + + + + Agora, vamos portar este exemplo para um pequeno aplicativo pa= ra internet. + + + + + + + EventManager um aplicativo para internet + + + Um aplicativo para internet do Hibernate usa uma Sess= ion e uma Transaction = + quase do mesmo modo que um aplicativo standalone. Entretanto, = alguns patterns comuns s=C3=A3o =C3=BAteis. = + N=C3=B3s agora criaremos um EventManagerServlet. Esse servlet lista todos os eventos = + salvos no banco de dados, e cria um formul=C3=A1rio HTML para = entrada de novos eventos. + + + + Criando um servlet b=C3=A1sico + + + Crie uma nova classe no seu diret=C3=B3rio fonte, no pacot= e events: + + + + + + O servlet manuseia somente requisi=C3=A7=C3=B5es = GET do HTTP, = + portanto o m=C3=A9todo que iremos implementar =C3=A9 doGet(): + + + + + + O pattern que estamos aplicando neste c=C3=B3digo =C3=A9 c= hamado session-per-request. + Quando uma requisi=C3=A7=C3=A3o chega ao servlet, uma nova= Session do Hibernate =C3=A9 = + aberta atrav=C3=A9s da primeira chamada para getC= urrentSession() em = + SessionFactory. Ent=C3=A3o uma transa= =C3=A7=C3=A3o do banco de dados =C3=A9 inicializada - = + todo acesso a dados deve ocorrer dentro de uma transa=C3= =A7=C3=A3o, n=C3=A3o importando se o dado =C3=A9 de leitura ou escrita. + (n=C3=B3s n=C3=A3o devemos usar o modo auto-commit em apli= ca=C3=A7=C3=B5es). + + + + Do not use a new Hibernate Session for + every database operation. Use one Hibernate Session that is + scoped to the whole request. Use getCurrentSession(), so that + it is automatically bound to the current Java thread. + + + Agora, as possibilidades de a=C3=A7=C3=B5es de uma requisi= =C3=A7=C3=A3o ser=C3=A3o processadas e uma resposta HTML ser=C3=A1 renderiz= ada. = + N=C3=B3s j=C3=A1 iremos chegar nesta parte. + + + + Finalmente, a unidade de trabalho termina quando o process= amento e a restitui=C3=A7=C3=A3o s=C3=A3o completados. = + Se ocorrer algum erro durante o processamento ou a restitu= i=C3=A7=C3=A3o, uma exce=C3=A7=C3=A3o ser=C3=A1 lan=C3=A7ada e a = + transa=C3=A7=C3=A3o do banco de dados encerrada. Isso comp= leta o pattern session-per-request. = + Em vez de usar c=C3=B3digo de demarca=C3=A7=C3=A3o de tran= sa=C3=A7=C3=A3o em todo servlet voc=C3=AA pode tamb=C3=A9m criar um filtro = servlet. = + D=C3=AA uma olhada no site do Hibernate e do Wiki para mai= ores informa=C3=A7=C3=B5es sobre esse pattern, = + chamado Open Session in View. + + + + + + Processando e renderizando + + + Vamos implementar o processamento da requisi=C3=A7=C3=A3o = e a restitui=C3=A7=C3=A3o da p=C3=A1gina HTML. + + +Event Manager"); + +// Handle actions +if ( "store".equals(request.getParameter("action")) ) { + + String eventTitle =3D request.getParameter("eventTitle"); + String eventDate =3D request.getParameter("eventDate"); + + if ( "".equals(eventTitle) || "".equals(eventDate) ) { + out.println("Please enter event title and date."); + } else { + createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate)); + out.println("Added event."); + } +} + +// Print page +printEventForm(out); +listEvents(out, dateFormatter); + +// Write HTML footer +out.println(""); +out.flush(); +out.close();]]> + + + O estilo de c=C3=B3digo acima, misturando linguagem HTML e= Java n=C3=A3o ser=C3=A1 funcional em um aplicativo = + mais complexo—tenha em mente que neste manual n=C3= =B3s estamos apenas ilustrando conceitos = + b=C3=A1sicos do Hibernate. O c=C3=B3digo imprime um cabe= =C3=A7alho HTML e um rodap=C3=A9. Dentro desta p=C3=A1gina, = + =C3=A9 mostrado um formul=C3=A1rio em HTML, para entrada d= e novos eventos, e uma lista de todos = + os eventos contidos no banco de dados. O primeiro m=C3=A9t= odo =C3=A9 trivial e apenas imprime = + uma p=C3=A1gina HTML: + + + Add new event:"); + out.println("
"); + out.println("Title:
"); + out.println("Date (e.g. 24.12.2009):
"); + out.println(""= ); + out.println("
"); +}]]>
+ + + O m=C3=A9todo listEvents() usa a Session do Hibernate = + associada a thread atual para executar um query: + + + 0) { + out.println("

Events in database:

"); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + for (Iterator it =3D result.iterator(); it.hasNext();) { + Event event =3D (Event) it.next(); + out.println(""); + out.println(""); + out.println(""); + out.println(""); + } + out.println("
Event titleEvent date
" + event.getTitle() + "" + dateFormatter.format(event.getDate()) + "=
"); + } +}]]>
+ + + Finalmente, a action store =C3=A9 passa= da pra o m=C3=A9todo = + createAndStoreEvent(), que tamb=C3=A9m = usa a = + Session da thread atual: + + + + + + Pronto, o servlet est=C3=A1 completo. Uma requisi=C3=A7=C3= =A3o para o servlet ser=C3=A1 processada = + em uma Session e uma Transac= tion simples. = + Como anteriormente, no aplicativo standalone, o Hibernate = pode automaticamente = + associar esses objetos a thread atual em execu=C3=A7=C3=A3= o. Isso possibilita a liberdade = + de voc=C3=AA modelar seu c=C3=B3digo e acessar o m=C3=A9to= do SessionFactory = + do jeito que achar melhor. Geralmente voc=C3=AA ir=C3=A1 u= sar um design mais sofisticado = + e mover o c=C3=B3digo de acesso a dados para dentro de obj= etos de acesso a dados = + (o patter DAO). Leia o Hibernate Wiki para maiores exemplo= s. + + +
+ + + Instalando e testando + + + Para fazer o deploy desta aplica=C3=A7=C3=A3o voc=C3=AA te= m que criar um arquivo para web, um WAR. = + Adicione o alvo Ant abaixo em seu build.xml: + + + + + + + + + + +]]> + + + Esta target cria um arquivo chamado hibernate-tut= orial.war = + no diret=C3=B3rio do seu projeto. Ele empacota todas as bi= bliotecas e o arquivo de = + descri=C3=A7=C3=A3o web.xml, o qual =C3= =A9 esperado no diret=C3=B3rio base do seu projeto: + + + + + + + Event Manager + events.EventManagerServlet + + + + Event Manager + /eventmanager + +]]> + + + Antes de voc=C3=AA compilar e fazer o deploy desta aplica= =C3=A7=C3=A3o web, note que uma biblioteca = + adicional =C3=A9 requerida: jsdk.jar. E= sse =C3=A9 o Java servlet development kit, = + se voc=C3=AA n=C3=A3o possui esta biblioteca, fa=C3=A7a se= u download na p=C3=A1gina da Sun e copie-a + para seu diret=C3=B3rio de bibliotecas. Entretanto, ser=C3= =A1 usado somente para a compila=C3=A7=C3=A3o e = + exclu=C3=ADdo do pacote WAR. + + + + Para compilar e instalar execute ant war no seu diret=C3=B3rio do projeto = + e copie o arquivo hibernate-tutorial.war para o diret=C3=B3rio = + webapp do Tomcat. Se voc=C3=AA n=C3=A3o= possui o Tomcat instalado fa=C3=A7a = + o download e siga as instru=C3=A7=C3=B5es de instala=C3=A7= =C3=A3o. Voc=C3=AA n=C3=A3o precisa modificar = + nenhuma configura=C3=A7=C3=A3o do Tomcat para rodar este a= plicativo. + + + + Uma vez feito o deploy e com Tomcat rodando, acesse o apli= cativo em = + http://localhost:8080/hibernate-tutorial/eventman= ager. = + Veja o log do Tomcat para observar a inicializa=C3=A7=C3= =A3o do Hibernate quando a = + primeira requisi=C3=A7=C3=A3o chega ao servlet (o iniciali= zador est=C3=A1tico dentro de = + HibernateUtil =C3=A9 chamado) e para te= r uma depura=C3=A7=C3=A3o = + detalhada se ocorrer alguma exce=C3=A7=C3=A3o. = + + + + +
+ + + Sum=C3=A1rio + + + Este manual cobriu os princ=C3=ADpios b=C3=A1sicos para cria= =C3=A7=C3=A3o de uma aplica=C3=A7=C3=A3o simples do Hibernate = + e uma pequena aplica=C3=A7=C3=A3o web. = + + + + Se voc=C3=AA j=C3=A1 se sente seguro com o Hibernate, continue= navegando na documenta=C3=A7=C3=A3o de refer=C3=AAncia = + por t=C3=B3picos que voc=C3=AA acha interessante =E2=80=93 os = t=C3=B3picos mais questionados s=C3=A3o: = + processo de transa=C3=A7=C3=A3o (), uso da API () = + e caracter=C3=ADsticas de consulta (). + + + + N=C3=A3o esque=C3=A7a de visitar o site do Hibernate para obte= r mais tutoriais especializados. + + + + +
Modified: core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xm= l.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml = 2007-10-26 00:46:38 UTC (rev 14135) +++ core/trunk/documentation/manual/pt-BR/src/main/docbook/content/xml.xml = 2007-10-26 00:48:48 UTC (rev 14136) @@ -1,7 +1,7 @@ = -=EF=BB=BF=EF=BB=BF + Mapeamento XML = --===============0672044846751291962==--