Resumo_Anotacoes_Certificacao_SCBCD_5.txt===============================================================================Re...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                        . O objeto não precisa ser serializável, o fornecedoresco...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                                <session>                                        ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt            public EJBHome getEJBHome( ) java.lang.IllegalStateException;        ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                               - Qualquer objeto java serializavel               ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt        . Escopo de Transação                PersistenceContextType.TRANSACTION  ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                   @PersistenceUnit(unitName=”toto”)                   public voi...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                . Se ela não for acoplada ao próprio EntityManager que invoca omé...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt               ...       }        <entity-mappings>                <entity class=...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                        sequence-name="CUST_SEQ"                        initial-v...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt               public String getLastName( ) { return this.lastName; }            ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                Para mapear um atributo do tipo enum. Pode ser ORDINAL ouSTRING, ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt@Entitypublic class Customer {...        @OneToOne(cascade={CascadeType.ALL})    ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtpublic class Customer {...        @OneToMany(cascade={CascadeType.ALL})    @JoinC...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt...          @OneToMany(mappedBy="cruise")      private Collection<Reservation> r...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt      private Set<Customer> customers = new HashSet<Customer>( );...}@Entitypubli...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt        @JoinTable                É utilizada uma tabela de junção de IDs para re...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt- Herança: Table Per Concrete Class        Schema: é gerada uma tabela para cada ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt          @Entity          @AttributeOverride(name="lastname", column=@Column(nam...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                  public void postInsert(Object entity) { ...     }              ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt               </entity-listeners>       </entity>- Declarando "Listeners Padrão"...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtEntityNotFoundException                                . Encontrou mais de um reg...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt       . Considerações Gerais               - As clausulas não são case-sensitive...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt               public class Name {                       private String first;   ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtTX, MI, WI, MN)                SELECT c FROM Customer AS c WHERE c.address.state ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                SELECT DISTINCT COUNT(c.address.zip) FROM Customers AS c WHEREc.a...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt- Scalar Native Queries          Query createNativeQuery(String sql)          . U...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt------------------------------------------- Queryes Nomeadas        . EJBQL Named...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtentrega da mensagem                - Ciclo de Vida: idêntico ao do Stateless Bean...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt        consumer.setMessageListener(this); //ou qualquer instancia queimplemente ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt                                int customerPk =reservationMsg.getInt("CustomerID...
Resumo_Anotacoes_Certificacao_SCBCD_5.txt<activation-config-property-name>acknowledgeMode</activation-config-property-name...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtintervalDuration, Serializable info)                        . De intervalo       ...
Resumo_Anotacoes_Certificacao_SCBCD_5.txtinvocation.getMethod( ) + " took " + endTime + " (ms)");                         ...
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
Upcoming SlideShare
Loading in …5
×

Resumo Anotacoes Certificacao SCBCD 5

2,338 views

Published on

Meus resumos e anotações da época que fiz a prova de certificação java SCBCD 5 (nova OCPBCD).

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,338
On SlideShare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
28
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Resumo Anotacoes Certificacao SCBCD 5

  1. 1. Resumo_Anotacoes_Certificacao_SCBCD_5.txt===============================================================================Resumo Anotações para Certificação SCBCD 5.0Autor: Gilberto Augusto Holms @gibaholms gibaholms85@gmail.com http://gibaholms.wordpress.com/===============================================================================- Introdução . EJB: Modelo de componentes padrão do lado do servidor para aplicativosde negócio distribuídos - Escalonáveis - Transacionais - Seguros com multi-usuários . Bean de Entidade (JPA): - A JPA pode funcionar sozinha, porém o container EJB3 forneceintegração adicional. - É um POJO, e não um componente (como era no 2.1). - Obrigatório uma chave primária ( @Id ), que pode ser umprimitivo ou uma classe. - As anotations podem estar tanto nos atributos quanto nosmétodos GETTER. . Persistence.xml - É obrigatório - Sobrescreve as annotations - Deployado num JAR junto com as entidades - Pode declarar várias Persistence Units - Persistence Unit -> composta por Entidades, representa umabase de dados . Interfaces de Negocio -> obrigatório ao menos uma interface de negócio - javax.ejb.Local (não utiliza protocolos distribuídos paraacessar – apenas mesma JVM) - javax.ejb.Remote - javax.jms.MessageListener - javax.jws.WebService . Container EJB, seis serviços primários: - Concorrência - Transação - Persistência - Distribuição de Objetos - Atribuição de Nomes (JNDI) - Segurança - Mensageria Assíncrona - Temporização . Serviços que melhoram o desempenho para grande número de clientes ebeans instanciados: - Pool de instâncias (Beans Stateless e MDB): . Clientes nunca acessam um bean diretamente, portanto ocontainer pode criar um pool de instancias e gerenciá-lo reaproveitando recursos. Uma mesma instânciaserve vários clientes (um de cada vez). - Ativação (Beans Statefull) . As variáveis de instância do bean são persistidas emum armazenamento secundário, e o bean é removido da memória (apassivação). Quando é invocado outrométodo, uma nova instância é criada e seu estado anterior é recuperado do armazenamento (ativação). Porém, o Stubnão perde a conexão durante a apassivação. Página 1
  2. 2. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . O objeto não precisa ser serializável, o fornecedorescolhe um método de ativação que independa disso. Para atributos transientes, o comportamento depende daimplementação do container. . É fornecido o callback @PrePassivate e @PostActivate.Serviços de contexto e o EntityManager devem ser mantidos durante o processo de apassivação. . Java EE Connectors (JCA) . Fornece mecanismo para criação de interfaces entre o containere sistemas legados, permitindo que os legados disparem mensagens para MDBs do conteiner. . Concorrência: . Beans se sessão não executam em multithread, portanto éproibido utilizar a palavra synchronized e também é proibido criar threads dentro de beans, pois o container precisater certeza que está com o controle sobre o comportamento de todas as instancias do bean. . Beans de entidade podem ser acessados de forma concorrente, ocontainer pode utilizar Optimistic Locking ou isolamento Serialized no JDBC. . Beans de mensagem podem processar mensagens simultaneamente,onde cada instancia do pool pode processar uma mensagem.- Session Beans . Interface Remota - Todos os parametros são copiados, inclusive os objetos, mesmose estiver na mesma JVM (chamada "por valor") @Remote public interface MyBusinessInterfaceRemote { ... } . Interface Local - Precisa estar na mesma JVM - Os parametros possuem comportamento normal, onde objetos sãopassados por referência (chamada "por referência) @Local public interface MyBusinessInterfaceLocal { ... } . Obs.: - Parametros de tipo objeto precisam extender Serializable ouExternalizable para poderem ser transferidos pela rede - Podem lançar exceções. Deve-se lançar apenas exceções denegócio, e não de subsistemas Java - Uma exceção de aplicativo é propagada ao cliente, e qualquervariável de instância dela deve ser serializavel - Todas exceções de runtime são capturadas pelo container eempacotadas em EJBException - Pode declarar @Local(MyBusinessInterfaceLocal.class) nopróprio bean, não precisando ele declarar a implementação da interface explicitamente e nem precisandoanotar a interface. Idem para @Remote . Descritor de Implantação - Fica dentro do JAR do projeto EJB, em: META-INF/ejb-jar.xml . Exemplo de EJB via XML <ejb-jar> <enterprise-beans> Página 2
  3. 3. Resumo_Anotacoes_Certificacao_SCBCD_5.txt <session> <ejb-name>ProcessPaymentBean</ejb-name><remote>com.titan.processpayment.ProcessPaymentRemote</remote><local>com.titan.processpayment.ProcessPaymentLocal</local><ejb-class>com.titan.processpayment.ProcessPaymentBean</ejb-class> <session-type>Stateless</session-type> </session> </enterprise-beans> </ejb-jar>- SessionContext public interface javax.ejb.SessionContext extends javax.ejb.EJBContext { MessageContext getMessageContext( ) throwsIllegalStateException; <T> getBusinessObject(Class<T> businessInterface) throwsIllegalStateException; Class getInvokedBusinessInterface( ); //METODOS OBSOLETOS - LANÇAM EXCEPTION SE CHAMADOS EJBLocalObject getEJBLocalObject( ) throws IllegalStateException EJBObject getEJBObject( ) throws IllegalStateException; } . getBusinessObject Retorna uma referência (do tipo da interface deparametro) ao objeto EJB atual. É ilegal que um bean envie uma referencia this para outro bean, para issoserve este método . getInvokedBusinessInterface Retorna a classe da interface de negócio invocada para obean atual . Obs.: - Herda mais todos os métodos de EJBContext - O container injeta o SessionContext via anotação@Resource- EJBContext public interface EJBContext { public Object lookup(String name); // security methods public java.security.Principal getCallerPrincipal( ); public boolean isCallerInRole(java.lang.String roleName); // transaction methods public javax.transaction.UserTransaction getUserTransaction( )throws java.lang.IllegalStateException; public boolean getRollbackOnly( ) throwsjava.lang.IllegalStateException; public void setRollbackOnly( ) throwsjava.lang.IllegalStateException; // OBSOLETO public TimerService getTimerService( ) throwsjava.lang.IllegalStateException; // METODOS OBSOLETOS - LANÇAM RuntimeException SE CHAMADOS public java.security.Identity getCallerIdentity( ); public boolean isCallerInRole(java.security.Identity role); public java.util.Properties getEnvironment( ); Página 3
  4. 4. Resumo_Anotacoes_Certificacao_SCBCD_5.txt public EJBHome getEJBHome( ) java.lang.IllegalStateException; public EJBLocalHome getEJBLocalHome( )java.lang.IllegalStateException; public Properties getEnvironment(); } . getCallerPrincipal Retorna o objeto Principal referente a quem estáacessando o bean . isCallerInRole Retorna se o usuário atual pertence a determinada role . lookup Permite pesquisar entradas no ENC do EJB.--------------------------------------------------------------------------------------------------------------------------- Stateless Session Beans @Stateless public class MyBean implements MyBusinessInterface {...} . Ciclo de Vida (TODO) . Precisa de um construtor padrão . Métodos de ciclo de vida: @PostConstruct Após o conteiner instanciar o bean (não significa sairdo pool) @PreDestroy Antes do container destruir o bean (não significa voltarpro pool). Durante a chamada, ainda estão disponíveis SessionContext e JNDI ENC . Obter a referência remota não indica que o bean saiu do pool. O beansai do pool e é configurado para o cliente apenas depois que o cliente invoca o primeiro método do bean--------------------------------------------------------------------------------------------------------------------------- Statefull Sessson Beans @Statefull public class MyBean implements MyBusinessInterface {...} . Ciclo de Vida (TODO) . Precisa de um construtor padrão . Métodos de ciclo de vida: @PostConstruct Após o conteiner instanciar o bean @PreDestroy Antes do container destruir o bean. Durante a chamada,ainda estão disponíveis SessionContext e JNDI ENC @PrePassivate Antes do bean ser apassivado (serializado paraarmazenamento de estado). Deve liberar recursos e setar campos transient com valores nulos. Objetos que são passivados e gerenciadosautomaticamente: - Tipos primitivos Página 4
  5. 5. Resumo_Anotacoes_Certificacao_SCBCD_5.txt - Qualquer objeto java serializavel - SessionContext - UserTransaction - javax.naming.Context - EntityManager - EntityManagerFactory - Fabricas injetadas por @Resource - Referencias injetadas por @EJB @PostActivate Depois do bean ser ativado (desserializado pararecuperação de estado). Foge à regra da desserialização java no que se trata de variáveis transient, cujo valorassumido será aleatório, e não o valor padrão, portanto este método deve reabrir os recursos e setaressas variáveis . O beans Statefull é removido da memória quando: - É chamado o método @Remove - O container detecta que deu timeout e o bean expirou (não podeexpirar durante uma transação) - @PreDestroy é chamado apenas no caso do @Remove. Em caso deexpiração, depende do fornecedor a chamada desse método ou não . Apenas obter a referência remota já cria uma sessão dedicada aocliente, porém não cria a instância. A instância é criada depois de chamar o primeiro método do bean . No caso de beans Statefull aninhados, a sessão do filho pertence aopai, ou seja, se o cliente remove o pai, o pai remove o filho automaticamente . Contexto de Persistencia Extendido: - Pode apenas em bean Statefull - Faz com que todas as Entidades mantenham-se gerenciadasdurante diferentes invocações de métodos - Se ele contiver outro bean Statefull aninhado, e esse bean:tiver interface local e também tiver contexto extendido, os dois beans compartilham o mesmo contextode persistencia extendido (mesmo EntityManager)- Entity Manager @Stateless public class MyBean implements MyBusinessInterface { @PersistenceContext(unitName="titan",type=PersistenceContextType.TRANSACTION) private EntityManager manager; ... } . Atributo type é opcional, o padrão vem TRANSACTION, maspodemos optar por EXTENDED. Se for TRANSACTION, diferentes instancias deEntityManager injetadas em beans diferentes estarão no mesmo contexto de persistência, até que a transaçãogeral termine O tipo EXTENDED pode ser utilizado apenas em beans@Statefull, e esse contexto dura o mesmo tempo de vida da instancia do bean (as transações em particularprecisam ser demarcadas). . Contexto de Persistência Tempo em que as entidade são gerenciadas pelo EntityManager.Quando o contexto de persistencia acaba, todas as entidades tornam-se detached. Página 5
  6. 6. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . Escopo de Transação PersistenceContextType.TRANSACTION O contexto de persistência dura exatamente o tempo deuma transação JTA, pode apenas ser utilizado em servidores J2EE, com entidades injetadas via@PersistenceContext PersistenceContextType.EXTENDED O contexto de persistência permanece ativo durantevárias transações, pode ser utilizado apenas em beans Statefull . Arquivo persistence.xml É obrigatório: <persistence> <persistence-unit name="titan"><jta-data-source>java:/OracleDS</jta-data-source> <properties> <propertiename="org.hibernate.hbm2ddl">update</propertie> </properties> </persistence-unit> </persistence> Obs.: <persistence-unit> atributo name – obrigatório atributo transaction-type – opcional (conf. JTApara servers J2EE ou RESOURCE_LOCAL para Java SE) outras tags opcionais: <description> <provider> : provedor de persistência (para J2EEvem o default do container) <non-jta-data-source> <mapping-file> : outro arquivo de mapeamento(container procura orm.xml e outros listados aqui) <jar-file> : carregar outro jar de entidades <class> : carregar classes específicas <exclude-unlisted-classes> : não carregarqualquer classe que não esteja declarada no persistence.xml (o jar default éignorado) . Empacotamento Sempre um arquivo jar com persistence.xml dentro de seu META-INF(se houver, o arquivo orm.xml também deve estar nessa pasta) . Classpath Java SE <JAR AQUI> . EJB-JAR . WAR > WEB-INF > lib <JAR AQUI> . EAR <JAR AQUI> . EAR > lib <JAR AQUI>--------------------------------------------------------------------------------------------------------------------------- Entity Manager Factory @Stateless public class FactoryBean implements FactoryBusinessInterface { @PersistenceUnit(unitName=”titan”) private EntityManagerFactory factory1; private EntityManagerFactory factory2; Página 6
  7. 7. Resumo_Anotacoes_Certificacao_SCBCD_5.txt @PersistenceUnit(unitName=”toto”) public void setFactory2(EntityManagerFactory factory2) {...} } . Não pode chamar método close() no EntityManagerFactory nem noEntityManager se eles forem injetados pelo container (lança IllegalStateException), pois o container cuida dessa limpeza. . O container injeta em um atributo ou em um setter . Se criar o EntityManager utilizando o factory, as transações serão deescopo extendido, ou seja, é preciso chamar EntityManager.joinTransaction()--------------------------------------------------------------------------------------------------------------------------- Métodos de EntityManager persist(Object entity) .Enfileira a entidade para criação no banco (não representa omomento real do insert) . É possível chamar persist fora de uma transação apenas seo contexto for EXTENDED, nesse caso, a inserção é enfileirada até o contexto ser associado com uma transação . Se o parâmetro não for uma entidade, lançaIllegalArgumentException . Se for invocado fora do contexto de transação e for tipoTRANSACTION, lança uma TransactionRequiredException joinTransaction() . Usado apenas se o contexto for criado pelaEntityManagerFactory . Associa o contexto de persistência à transação . Obs.: se o contexto for gerenciado pelo container, ele éassociado automaticamente (não precisa desse método) find(Class<T> entityClass, Object pk) : Entidade getReference(Class<T> entityClass, Object pk) : Entidade . Retornam uma entidade a partir de sua chave primária . O find, se não encontrar retorna null, e utiliza asconfigurações de lazy-loading . O getReference, se não encontrar lança EntityNotFoundException . Se o contexto de persistência estiver ativo, ela é acoplada,senão ela é desacoplada createQuery e createXXXQuery . Executam querys EJB-QL e consultas nativas (retornam um objetoQuery) . Entidades retornadas permanegem gerenciadas enquanto ocontexto de persistência estiver ativo flush() . Sincroniza as atualizações no banco antes de terminar atransacao merge(Object entity) : Entidade . Atualiza uma entidade desacoplada e retorna uma cópia delaacoplada . ATENÇÃO: o objeto de parâmetro nunca é gerenciado peloEntityManager, e sim sua cópia que retorna. Se ele já estiver gerenciado a mesma instancia, ele atualiza ela eretorna sua referencia. remove(Object entity) Remove a entidade da base e torna ela desacoplada refresh(Object entity) . Atualiza a entidade acoplada com os dados da base Página 7
  8. 8. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . Se ela não for acoplada ao próprio EntityManager que invoca ométodo, é lançada IllegalArgumentException . Se o objeto não estiver mais no banco devido outra Thread ouProcesso ter removido ele, será lançado EntityNotFoundException contains(Object entity) : Boolean . Retorna true se a entidade estiver acoplada, false casocontrario. clear() . Desacopla todas as entidades atuais gerenciadas peloEntityManager . Suas modificações são perdidas, portanto é prudente chamarflush() antes. setFlushMode(FlushModeType tp) . Pode receber FlushModeType.AUTO ou FlushModeType.COMMIT . AUTO - é o padrão, onde a implementação da JPA decidequando quer fazer o flush(), onde é certo apenas que ele fará no final da transação, mas também fazer antes . COMMIT - força para que ele sincronize apenas no finalda transação. COMMIT Melhora a performance pois cada atualização requer um bloqueio, e fazer todas de uma vezé mais rápido getDelegate() : EntityManagerImpl . Retorna uma instancia ao objeto do fornecedor do implementadorEntityManager, que pode proporcionar extensões à JPA padrão--------------------------------------------------------------------------------------------------------------------------- EntityTransaction É a API de transação fornecida como alternativa à JTA. Ela pode serusada apenas se o atributo transaction-type for RESOURCE_LOCAL. Permite utilizar begin(), commit() e rollback()manualmente. EntityTransaction et = myEntityManager.getTransaction(); et.begin(); myEntityManager.persist(myEntity); et.commit(); . O método begin() lança IllegalStateException se já houver umatransação ativa, commit() e rollback() lançam a mesma exceção se não houver transação ativa.- Criando Entidades @Entity @Table(name="CUSTOMER_TABLE", catalog="TITAN", schema="TITAN", uniqueConstraints=@UniqueConstraint(columnNames={"EMP_ID","EMP_NAME"}) ) public class Customer { @Id @GeneratedValue @Column(name="CUST_ID", nullable=false,columnDefinition="integer") private int id; @Column(name="FIRST_NAME", length=20, nullable=false) private String firstName; Página 8
  9. 9. Resumo_Anotacoes_Certificacao_SCBCD_5.txt ... } <entity-mappings> <entity class="com.titan.domain.Customer" access="PROPERTY"><!-- PROPERTY e FIELD não se misturam --> <table name="CUSTOMER_TABLE"> <unique-constraint><column-name>SOME_OTHER_ATTRIBUTE</column_name> </unique-constraint> </table> <attributes> <id name="id"> <column name="CUST_ID" nullable="false"column-definition="integer"/> <generated-value strategy="AUTO"/> </id> <basic name="firstName"> <column name="FIRST_NAME"nullable="false" length="20"/> </basic> </attributes> </entity> </entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Tipos de geradores de PK @GeneratedValue ou @GeneratedValue(strategy=GeneratorType.AUTO) <attributes> <id name="id"> <generated-value strategy="AUTO"/> </id> </attributes> @TableGenerator(name="CUST_GENERATOR" table="GENERATOR_TABLE" pkColumnName="PRIMARY_KEY_COLUMN" valueColumnName="VALUE_COLUMN" pkColumnValue="CUST_ID" allocationSize=10 ) @GeneratedValue(strategy=GenerationType.TABLE,generator="CUST_GENERATOR") <table-generator name="CUST_GENERATOR" table="GENERATOR_TABLE" pk-column-name="PRIMARY_KEY_COLUMN" value-column-name="VALUE_COLUMN" pk-column-value="CUST_ID" allocation-size="10" /> <attributes> <id name="id"> <generated-value strategy="TABLE"generator="CUST_GENERATOR"/> </id> </attributes> @SequenceGenerator(name="CUSTOMER_SEQUENCE", sequenceName="CUST_SEQ") @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="CUSTOMER_SEQUENCE") <sequence-generator name="CUSTOMER_SEQUENCE" Página 9
  10. 10. Resumo_Anotacoes_Certificacao_SCBCD_5.txt sequence-name="CUST_SEQ" initial-value="0" allocation-size="50"/> <attributes> <id name="id"> <generated-value strategy="SEQUENCE"generator="CUSTOMER_SEQUENCE"/> </id> </attributes>--------------------------------------------------------------------------------------------------------------------------- PK Compostas: Por PK Class public class CustomerPK implements java.io.Serializable { private String lastName; private long ssn; public String getLastName( ) { return this.lastName; } public void setLastName(String lastName) { this.lastName =lastName; } public long getSsn( ) { return ssn; } public void setSsn(long ssn) { this.ssn = ssn; } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof CustomerPK)) return false; CustomerPK pk = (CustomerPK)obj; if (!lastName.equals(pk.lastName)) return false; if (ssn != pk.ssn) return false; return true; } public int hashCode( ) { return lastName.hashCode( ) + (int)ssn; } } @Entity @IdClass(CustomerPK.class) public class Customer { private String firstName; private String lastName; private long ssn; @Id public String getLastName( ) { return lastName; } public void setLastName(String lastName) { this.lastName =lastName; } @Id public long getSsn( ) { return ssn; } public void setSsn(long ssn) { this.ssn = ssn; } } Requerimentos para a PK Class: . It must be serializable . It must have a public no-arg constructor . It must implement the equals( ) and hashCode( ) methods.- PK Compostas: Por Embeddable Class @Embeddable public class CustomerPK implements java.io.Serializable { private String lastName; private long ssn; Página 10
  11. 11. Resumo_Anotacoes_Certificacao_SCBCD_5.txt public String getLastName( ) { return this.lastName; } public void setLastName(String lastName) { this.lastName =lastName; } public long getSsn( ) { return ssn; } public void setSsn(long ssn) { this.ssn = ssn; } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof CustomerPK)) return false; CustomerPK pk = (CustomerPK)obj; if (!lastName.equals(pk.lastName)) return false; if (ssn != pk.ssn) return false; return true; } public int hashCode( ) { return lastName.hashCode( ) + (int)ssn; } } @Entity public class Customer { private String firstName; private CustomerPK pk; @EmbeddedId public PK getPk( ) { return pk; } public void setPk(CustomerPK pk) { this.pk = pk; } } Obs.: Podemos sobrescrever as anotações @Column feitas na classe da PK(não podemos utilizar @Column na classe entidade, pois o nome da coluna á definida na classe de PK) @EmbeddedId @AttributeOverrides({ @AttributeOverride(name="lastName",column=@Column(name="LAST_NAME"), @AttributeOverride(name="ssn",column=@Column(name="SSN")) })--------------------------------------------------------------------------------------------------------------------------- Mapeando Atributos @Transient Campo não é criado na base @Basic(fetch=FetchType.LAZY, optional=false) Se o campo é obrigatório, e permite lazy loading do campo (poréma especificação não garante o lazy loading real, depende da implementação) @Temporal(TemporalType.TIME) Define o tipo real a gerar na base para um tipo de data java(DATE, TIME, TIMESTAMP) @Lob Define que será um tipo binário (blob) ou um tipo sequencial decaracteres (clob). O tipo real gerado depende do tipo de atributo: BLOB: byte[], Byte[], or java.io.Serializable CLOB: char[], Character[], or java.lang.String @Enumerated(EnumType.STRING) Página 11
  12. 12. Resumo_Anotacoes_Certificacao_SCBCD_5.txt Para mapear um atributo do tipo enum. Pode ser ORDINAL ouSTRING, onde ORDINAL grava o numero do indice do campo no enum e STRING grava o proprio nome do enum.--------------------------------------------------------------------------------------------------------------------------- Mapeamentos Multi-Table @Entity @SecondaryTable(name="ADDRESS_TABLE",pkJoinColumns={@PrimaryKeyJoinColumn(name="ADDRESS_ID")}) public class Customer { private long id; private String firstName; private String street; private String city; ... @Column(name="STREET", table="ADDRESS_TABLE") public String getStreet( ) { return street; } public void setStreet(String street) { this.street = street; } @Column(name="CITY", table="ADDRESS_TABLE") public String getCity( ) { return city; } public void setCity(String city) { this.city = city; } ... } Obs.: É suportado mais de uma tabela secundária: @SecondaryTables({ @SecondaryTable(name="ADDRESS_TABLE",pkJoinColumns={@PrimaryKeyJoinColumn (name="ADDRESS_ID")}), @SecondaryTable(name="CREDIT_CARD_TABLE",pkJoinColumns={@PrimaryKeyJoinColumn (name="CC_ID")}) })--------------------------------------------------------------------------------------------------------------------------- Campos de Embeddable Objects @Embeddable public class Address { private String street; private String city; private String state; } @Entity public class Customer { private long id; private String firstName; private String lastName; @Embedded private Address address; } Obs.: como as colunas geradas pela classe embedded são definidas dentrodela, também vale o conceito de @AttributeOverrides para definir outras caracteristicas de coluna dentroda classe utilizadora--------------------------------------------------------------------------------------------------------------------------- Unidirecional "Um-Para-Um" Página 12
  13. 13. Resumo_Anotacoes_Certificacao_SCBCD_5.txt@Entitypublic class Customer {... @OneToOne(cascade={CascadeType.ALL}) private Address address;...}<entity-mappings> <entity class="com.titan.domain.Customer" access="FIELD"> <!-- ouaccess="PROPERTY" --> <attributes> <id name="id"> <generated-value/> </id> <one-to-one name="address"targetEntity="com.titan.domain.Address" fetch="LAZY" optional="true"> <cascade>ALL</cascade> <!-- ou <cascade-all/>--> <join-column name="ADDRESS_ID"/> <!-- ou<primary-key-join-column/> --> </one-to-one> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Bidirecional "Um-Para-Um"@Entitypublic class Customer {... @OneToOne(cascade={CascadeType.ALL}) private CreditCard creditCard;...}@Entitypublic class CreditCard {... @OneToOne(mappedBy="creditCard") private Customer customer;...}<entity-mappings> <entity class="com.titan.domain.Customer" access="FIELD"> ... </entity> <entity class="com.titan.domain.CreditCard" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <one-to-one name="customer"target-entity="com.titan.domain.Customer" mapped-by="creditCard"/> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Unidirecional "Um-Para-Muitos"@Entity Página 13
  14. 14. Resumo_Anotacoes_Certificacao_SCBCD_5.txtpublic class Customer {... @OneToMany(cascade={CascadeType.ALL}) @JoinColumn(name="CUSTOMER_ID") private Collection<Phone> phoneNumbers = new ArrayList<Phone>( );...}<entity-mappings> <entity class="com.titan.domain.Customer" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <one-to-many name="phones"targetEntity="com.titan.domain.Phone"> <cascade-all/> <join-column name="CUSTOMER_ID"/> <!-- ou<join-table name="CUSTOMER_PHONE"> --> </one-to-many> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Unidirecional "Muitos-Para-Um"@Entitypublic class Cruise {... @ManyToOne @JoinColumn(name="SHIP_ID") private Ship ship;...}<entity-mappings> <entity class="com.titan.domain.Cruise" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <many-to-one name="ship"target-entity="com.titan.domain.Ship" fetch="EAGER"> <join-column name="SHIP_ID"/> </many-to-one> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Bidirecional "Um-Para-Muitos" / "Muitos-Para-Um"@Entitypublic class Reservation {... @ManyToOne @JoinColumn(name="CRUISE_ID") private Cruise cruise;...}@Entitypublic class Cruise { Página 14
  15. 15. Resumo_Anotacoes_Certificacao_SCBCD_5.txt... @OneToMany(mappedBy="cruise") private Collection<Reservation> reservations = new ArrayList<Reservation>();...}<entity-mappings> <entity class="com.titan.domain.Cruise" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <one-to-many name="ship"target-entity="com.titan.domain.Reservation" fetch="LAZY" mapped-by="cruise" /> </attributes> </entity> <entity class="com.titan.domain.Reservation" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <many-to-one name="cruise"target-entity="com.titan.domain.Cruise" fetch="EAGER"> <join-column name="CRUISE_ID"/> </many-to-one> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Unidirecional "Muitos-Para-Muitos"@Entitypublic class Reservation {... @ManyToMany private Set<Customer> customers = new HashSet<Customer>( );...}<entity-mappings> <entity class="com.titan.domain.Reservation" access="PROPERTY"> <attributes> <id name="id"> <generated-value/> </id> <many-to-many name="cabins"target-entity="com.titan.domain.Cabin" fetch="LAZY" /> </attributes> </entity></entity-mappings>--------------------------------------------------------------------------------------------------------------------------- Bidirecional "Muitos-Para-Muitos"@Entitypublic class Reservation {... @ManyToMany @JoinTable(name="RESERVATION_CUSTOMER", joinColumns={@JoinColumn(name="RESERVATION_ID")}, inverseJoinColumns={@JoinColumn(name="CUSTOMER_ID")} ) Página 15
  16. 16. Resumo_Anotacoes_Certificacao_SCBCD_5.txt private Set<Customer> customers = new HashSet<Customer>( );...}@Entitypublic class Customer {... @ManyToMany(mappedBy="customers") private Collection<Reservation> reservations = new ArrayList<Reservation>();...}<entity-mappings> <entity class="com.titan.domain.Reservation" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <many-to-many name="customers"target-entity="com.titan.domain.Customer" fetch="LAZY"> <join-table name="RESERVATION_CUSTOMER"> <join-column name="RESERVATION_ID"/> <inverse-join-columnname="CUSTOMER_ID"/> </join-table> </many-to-many> </attributes> </entity> <entity class="com.titan.domain.Customer" access="FIELD"> <attributes> <id name="id"> <generated-value/> </id> <many-to-many name="cruise"target-entity="com.titan.domain.Reservation" fetch="LAZY" mapped-by="customers"/> </attributes> </entity></entity-mappings>-------------------------------------------------------------------------------------------------------------------------- @PrimaryKeyJoinColumn Utilizado no OneToOne, quando queremos que a associação nãoutilize um campo de chave estrangeira, neste caso a associação será feita gravando IDs de mesmo valor nasduas tabelas @PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name="ADDR_ID"), @PrimaryKeyJoinColumn(name="ADDR_ZIP") }) @JoinColumn(name="TOTO_ID") Indica a coluna que receberá a chave primária da outra tabela.Se quiser que referencia outra coluna que não seja a chave primária da tabela, utilizar o atributoreferencedColumnName (porem coluna nao pode ter repetição) @JoinColumns({ @JoinColumn(name="ADDR_ID"), @JoinColumn(name="ADDR_ZIP") }) É utilizado para chaves primárias compostas por mais de umacoluna Página 16
  17. 17. Resumo_Anotacoes_Certificacao_SCBCD_5.txt @JoinTable É utilizada uma tabela de junção de IDs para relacionamentosUm-Para-Muitos e Muitos-Para-Um Um-Para-Muitos: @JoinTable é padrão Muitos-Para-Um: @JoinColumn é padrão Muitos-Para-Muitos: apenas @JoinTable @OrderBy("lastname ASC, firstname DESC") Permite ordenação, serve apenas para relacionamento com List @MapKey(name="number") É utilizado para relacionamento com Map. O atributo name será oda key do Map, e a entidade relacionada será o value FetchType.EAGER e FetchType.LAZY (cuidados) Se a entidade estiver "detached" e seu relacionamento LAZY nãofor carregado, e tanter ser acessado, será lançada uma exceção do provedor de persistência (uma chamada ao .size()da coleção do relacionamento garante o load da coleção, ou o uso do operador FETCH JOIN da ejbql) Cruise detachedCruise = ... ; try { int numReservations =detachedCruise.getReservations().size(); } catch (SomeVendorLazyInitializationException ex) { } CascadeType - ALL, PERSIST, MERGE, REMOVE, REFRESH Realiza a respectiva operação do EntityManager para todas asentidades relacionadas. Aumenta a carga de calls na base e pode causar efeitos indesejáveis- Herança: Single Table Per Class Schema: é gerada uma tabela contendo todos os atributos de toda ahierarquia, adicionando uma coluna discriminadora, que identifica qual é o tipo. Person > Customer > Employee @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="DISCRIMINATOR",discriminatorType=DiscriminatorType.STRING) @DiscriminatorValue("PERSON") public class Person { ... } @Entity @DiscriminatorValue("CUST") public class Customer extends Person { ... } @Entity public class Employee extends Customer { ... } Obs.: @DiscriminatorColumn Pode ser STRING, CHAR ou INTEGER. Não é obrigatório, seomitido o default é STRING e o nome é gerado pelo fornecedor. @DiscriminatorValue Não é obrigatório, se omitido utiliza o nome da classe. Vantagens: É simples e performática, não requer joins e é boa paraselects polimorficos. Desvantagens: Todas as colunas de todas as subclasses precisam serNULLABLE, e não possui um modelo normalizado. Página 17
  18. 18. Resumo_Anotacoes_Certificacao_SCBCD_5.txt- Herança: Table Per Concrete Class Schema: é gerada uma tabela para cada classe concreta, cada tabelacontendo todos os atributos dessa classe e todos seus atributos herdados. Person > Customer > Employee @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class Person { ... } @Entity public class Customer extends Person { ... } @Entity public class Employee extends Customer { ... } Obs.: Vantagens: Pode ter constraints NOT NULL em qualquer campo, e olegado pode estar modelado dessa forma. Desvantagens: É mais lento, não é normalizado, possui camposredundantes e tem baixa performance num select polimorfico.- Herança: Table Per SubClass Schema: é gerada uma tabela para cada classe, cada tabela contendoapenas os atributos da classe, onde todas as tabelas são associadas pelas suas chaves primárias. Person > Customer > Employee @Entity @Inheritance(strategy=InheritanceType.JOINED) public class Person { ... } @Entity public class Customer extends Person { ... } @Entity @PrimaryKeyJoinColumn(name="EMP_PK") public class Employee extends Customer { ... } Obs.: A anotação @PrimaryKeyJoinColumn é obrigatória se as colunas daschaves primárias possuirem nomes diferentes nas tabelas. Vantagens: Pode ter constraints NOT NULL em qualquer campo e seumodelo é normalizado. Desvantagens: É mais lento que a SINGLE_TABLE.- Herança: Nonentity Base Classes @MappedSuperclass public class Person { @Id @GeneratedValue private int id; private String lastname; ... } Página 18
  19. 19. Resumo_Anotacoes_Certificacao_SCBCD_5.txt @Entity @AttributeOverride(name="lastname", column=@Column(name="SURNAME")) public class Customer extends Person { ... } Obs.: A superclasse não é uma entidade e nem é persistida, ela apenasfornece atributos persistentes para as suas subclasses, que podem ser sobrecarregados com o@AttributeOverrides / @AttributeOverride- Metodos de Callback @PrePersist - Quando uma entidade é agendada para inserção no banco de dados . Depois de persist() . Depois de merge() caso haja inserção aninhada emcascata @PostPersist - Quando a inserção real no banco de dados ocorre efetivamente . Depois do flush() se houver inserção infileirada . Depois que o contexto de persistencia atualiza o bancode dados (se for FlushType.COMMIT, é no final da transação) @PostLoad - Depois da entidade ser hidradata com os dados da base . Depois do find(), getReference() ou uma consultaEJB-QL @PreUpdate - Antes da entidade ser atualizada no banco de dados . Antes do flush() ou antes de o contexto depersistencia atualizar o banco de dados @PostUpdate - Depois da entidade ser atualizada no banco de dados . Depois do flush() ou depois de o contexto depersistencia atualizar o banco de dados @PreRemove - Quando uma entidade é agendada para remoção do banco de dados . Depois de remove() . Depois de merge() caso haja remoção aninhada emcascata @PostRemove - Quando a exclusão real no banco de dados ocorre efetivamente . Depois do flush() se houver exclusão infileirada . Depois que o contexto de persistencia atualiza o bancode dados (se for FlushType.COMMIT, é no final da transação) Obs.: Na classe de entidade: qualquer método que retorne void e nãoreceba argumentos Na classe listener: qualquer método que retorne void e recebacomo argumento um Object (conterá a instância da entidade em questão)--------------------------------------------------------------------------------------------------------------------------- Listeners de Entidade public class MeuListener1 { ... @PostPersist Página 19
  20. 20. Resumo_Anotacoes_Certificacao_SCBCD_5.txt public void postInsert(Object entity) { ... } ... } public class MeuListener2 { ... @PostPersist public void postPersist(Object entity) { ... } @PostLoad public void postLoad(Object entity) { ... } ... } @Entity @EntityListeners({MeuListener1.class, MeuListener2.class}) public class MyEntity { @PostPersist public void afterInsert() { ... } } Obs.: Chamados na ordem em que foram declarados em @EntityListeners ouno XML, por ultimo o da entidade postInsert() + postPersist() + afterInsert()- Herança de Listeners @Entity @EntityListeners({MeuListener1.class}) public class Person { @PostPersist public void parentAfterInsert() { ... } } @Entity @EntityListeners({MeuListener2.class}) public class Customer extends Person { @PostPersist public void childAfterInsert() { ... } } Obs.: Ordem de chamada: PostPersist de MeuListener1 PostPersist de MeuListener2 PostPersist de Person PostPersist de Customer Outras anotations: @ExcludeDefaultListeners Ignora os "Listeners Padrão" setados na unidadede persistencia @ExcludeSuperclassListeners Ignora os listeners herdados- Declarando Listeners com XML <entity class="com.titan.domain.Cabin"> <entity-listeners> <entity-listenerclass="com.titan.listeners.TitanAuditLogger" /> <entity-listenerclass="com.titan.listeners.EntityJmxNotifier"> <pre-persist name="beforeInsert"/> <post-load name="afterLoading"/> </entity-listener> Página 20
  21. 21. Resumo_Anotacoes_Certificacao_SCBCD_5.txt </entity-listeners> </entity>- Declarando "Listeners Padrão" Os listeners declarados dessa forma serão aplicados à todas entidades daunidade de persistencia: <entity-mappings> <entity-listeners> <entity-listenerclass="com.titan.listeners.EntityJmxNotifier"> <pre-persist name="beforeInsert"/> <post-load name="afterLoading"/> </entity-listener> </entity-listeners> </entity-mappings>- Conceitos Gerais EJBQL . Pode comparar primitivo com Wrapper e comparar valores temporais . Comparação de entidades na base é feita pela chave primaria . Clausula IN no from: itera a lista e faz join (corresponde a INNERJOIN ou somente JOIN) . Operadores valem apenas no WHERE . Clausula IN no where: verifica se valor está dentro da lista deLITERAIS: IN(X, Y, Z) . Relacionamento "Um-Para-Um" ou campo basico: IS NULL . Relacionamento baseado em coleção (muitos): IS EMPTY . Cuidado INNER JOIN com IS EMPTY (pag 136) . Cuidado: order by e campos que pode (pag 141) . Operações em lote (chamar antes: flush e clear)- Interface Query public interface Query { public List getResultList( ); public Object getSingleResult( ); public int executeUpdate( ); public Query setMaxResults(int maxResult); public Query setFirstResult(int startPosition); public Query setHint(String hintName, Object value); public Query setParameter(String name, Object value); public Query setParameter(String name, Date value, TemporalTypetemporalType); public Query setParameter(String name, Calendar value, TemporalTypetemporalType); public Query setParameter(int position, Object value); public Query setParameter(int position, Date value, TemporalTypetemporalType); public Query setParameter(int position, Calendar value, TemporalTypetemporalType); public Query setFlushMode(FlushModeType flushMode); } . Retornando Resultados Método getSingleResult try { Query query = entityManager.creatQuery( "from Customer c where c.firstName=Bill andc.lastName=Burke"); Customer cust = (Customer)query.getSingleResult(); } catch (EntityNotFoundException notFound) { } catch (NonUniqueResultException nonUnique) {} - Utilizado para retornar apenas um registro: . Não encontrou nenhum registro: Página 21
  22. 22. Resumo_Anotacoes_Certificacao_SCBCD_5.txtEntityNotFoundException . Encontrou mais de um registro:NonUniqueResultException Método getResultList Query query = entityManager.creatQuery( "from Customer c where c.firstName=Bill andc.lastName=Burke"); List bills = query.getResultList( ); - Utilizado para retornar uma coleção de registros: . Não encontrou nenhum registro: retorna umalista vazia . Parametros Parametros Nomeados Query query = entityManager.createQuery( "from Customer c where c.firstName=:first andc.lastName=:last"); query.setParameter("first", first); query.setParameter("last", last); Parametros Indexados Query query = entityManager.createQuery( "from Customer c where c.firstName=?1 and c.lastName=?2"); query.setParameter(1, first); query.setParameter(2, last); . Parametros Temporais Query query = entityManager.createQuery( "from Customer c where c.dataNascimento=?1"); query.setParameter(1, new java.util.Date,TemporalType.DATE); //DATE, TIME, TIMESTAMP . Paginação de Registros setFirstResult: seta o índice do primeiro registro a trazer setMaxResults: seta a quantidade máxima de registros a trazer Query query = entityManager.createQuery("from Customerc"); List customers =query.setMaxResults(max).setFirstResult(index).getResultList( ); Obs.: é perigoso trazer muitos registros de uma vez, pois todosficam gerenciados pelo EntityManager e o sistema fica pesado, recomenda-se trazer aos poucos dandoclear() no EntityManager . Hints Utilizado para setar na query um atributo específico defornecedor Query query = manager.createQuery("from Customer c"); query.setHint("org.hibernate.timeout", 1000); . FlushMode query.setFlushMode(FlushModeType.COMMIT); Indica que não deve haver nenhum flush antes da execuçãodesta query query.setFlushMode(FlushModeType.AUTO); É o default, deixa o container livre para fazer flushantes da query, se desejar--------------------------------------------------------------------------------------------------------------------------- Clausulas EJB-QL Página 22
  23. 23. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . Considerações Gerais - As clausulas não são case-sensitive - Os nomes de classes e atributos são case-sensitive . Abstract Schema Name @Entity public class Customer {...} ->entityManager.createQuery("SELECT c FROM Customer AS c"); @Entity(name="Cust") public class Customer {...} ->entityManager.createQuery("SELECT c FROM Cust AS c"); . Simple Queryes SELECT OBJECT( c ) FROM Customer AS c SELECT c FROM Customer AS c SELECT c FROM Customer c ERRO: SELECT customer FROM Customer AS customer O identificador não pode ter nome igual ao nome daentidade, independente do case dos caracteres SELECT c.firstName, c.lastName FROM Customer AS c Obs.: se a entidade for mapeada como tipo FIELD, acessapor nome do atributo, se for como tipo PROPERTY, acessa pelo nome do método JavaBeantransformado em nome de atributo Obs.: Se a query retornar uma entidade, os registros retornamcomo um List de entidades Se a query retornar campos escalares, os registrosretornam como um List de Object[] . Navegando Entidades SELECT c.creditCard.creditCompany.address FROM Customer AS c Efeito: Retorna o "address" da "creditCompany" da"creditCard" de todos "Customer" Obs.: Permite navegar por relacionamento "unário" ou poratributo @Embedded Exemplo 1: @Entity public class Address { private ZipCode zip; } ERRO: SELECT c.address.zip.mainCode FROMCustomer AS c Para tornar o select válido, deveria modificar oatributo para: @Embedded private ZipCode zip; Exemplo 2: @Entity public class Customer { @OneToMany private List<Phone> phones; } ERRO: SELECT c.phones.number FROM Customer AS c Isso seria o mesmo que customer.getPhones().getNumber( ); o que é INVALIDO. . Constructor Expressions Página 23
  24. 24. Resumo_Anotacoes_Certificacao_SCBCD_5.txt public class Name { private String first; private String last; public Name(String first, String last) { this.first = first; this.last = last; } } SELECT new myPackage.Name(c.firstName, c.lastName) FROM Customerc Efeito: Retorna uma List de objetos "Name" preenchidoscomo indicado no construtor . Clausula IN / INNER JOIN / JOIN / LEFT JOIN / XXX JOIN FETCH /DISTINCT SELECT r FROM Customer AS c, IN( c.reservations ) r Efeito: Retorna todas reservas de todos clientes Obs.: É idêndico a: = SELECT r FROM Customer AS c, INNER JOINc.reservations r = SELECT r FROM Customer AS c, JOINc.reservations r SELECT c.firstName, c.lastName, p.number FROM Customer c INNERJOIN c.phoneNumbers p Como no SQL, INNER JOIN irá retornar apenas campos ondeexiste associação não nula, ou seja, irá retornar apenas clientes que possuemtelefones associados SELECT c.firstName, c.lastName, p.number FROM Customer c LEFTJOIN c.phoneNumbers p Como no SQL, LEFT JOIN irá retornar também campos ondeexiste associação nula, ou seja, irá retornar todos clientes e, caso não possuatelefone associado, retornará null no objeto associativo SELECT c FROM Customer c LEFT JOIN FETCH c.phones Adicionando FETCH após o JOIN indica que se orelacionamento for LAZY, deverá carregar mesmo assim Evita o problema N+1, onde se executassemos getPhones()seriam feito N selects, desta forma é feito apenas um select. SELECT DISTINCT cust FROM Reservation AS res, IN (res.customers)cust Não retorna instancias duplicadas no resultado . Clausula WHERE / BETWEEN / IN / LIKE / IS NULL / IS EMPTY / MEMBER OF SELECT c FROM Customer AS c WHEREc.creditCard.creditCompany.name = Capital One SELECT s FROM Ship AS s WHERE s.tonnage = 100000.00 SELECT c FROM Customer AS c WHERE c.hasGoodCredit = TRUE SELECT r FROM Reservation AS r WHERE (r.amountPaid * .01) >300.00 SELECT r FROM Reservation r, IN ( r.customers ) AS cust WHEREcust = :specificCustomer SELECT s FROM Ship AS s WHERE s.tonnage BETWEEN 80000.00 AND130000.00 SELECT c FROM Customer AS c WHERE c.address.state IN (FL,TX, MI, WI, MN) SELECT c FROM Customer AS c WHERE c.address.state NOT IN (FL, Página 24
  25. 25. Resumo_Anotacoes_Certificacao_SCBCD_5.txtTX, MI, WI, MN) SELECT c FROM Customer AS c WHERE c.address.state IN ( ?1, ?2,?3, WI, MN) SELECT c FROM Customer AS c WHERE c.address IS NULL SELECT c FROM Customer AS c WHERE c.address IS NOT NULL SELECT crs FROM Cruise AS crs WHERE crs.reservations IS EMPTY SELECT crs FROM Cruise AS crs WHERE crs.reservations IS NOTEMPTY Obs.: Não pode utilizar IS EMPTY em um campo especificado noJOIN ERRO: SELECT r FROM Reservation AS r INNER JOINr.customers AS c WHERE r.customers IS NOT EMPTY ANDc.address.city = Boston Obs.: Na clausula like, % indica N caracteres e _ indica umcaractere SELECT OBJECT( c ) FROM Customer AS c WHERE c.lastName LIKE%-% SELECT OBJECT( c ) FROM Customer AS c WHERE c.lastName LIKEJoan_ Obs.: Clausula MEMBER OF é como se fosse o IN para tipos decoleção (contains) SELECT crs FROM Cruise AS crs, IN (crs.reservations) AS res,Customer AS cust WHERE cust = :myCustomer AND cust MEMBER OFres.customers . Clausulas Funcionais LOWER(String) UPPER(String) TRIM([[LEADING | TRAILING | BOTH] [trim_char] FROM] String) CONCAT(String1, String2) LENGTH(String) LOCATE(String1, String2 [, start]) SUBSTRING(String1, start, length) ABS(number) SQRT(double) MOD(int, int) CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP . Clausulas Agregadoras Obs.: se COUNT avalia uma coleção vazia, ele retorna zero SELECT COUNT( c ) FROM Customers AS c WHERE c.address.state =WI SELECT COUNT(c.address.zip) FROM Customers AS c WHEREc.address.zip LIKE 554% Obs.: MAX e MIN comparam qualquer tipo de dado (utiliza valor outamanho em bytes) SELECT MAX( r.amountPaid ) FROM Reservation AS r SELECT MAX( r.amountPaid ) FROM Reservation AS r Obs.: SUM e AVG servem apenas para numericos e wrappers SELECT SUM(r.amountPaid) FROM Cruise c join c.reservations rWHERE c = :cr Obs.: quando utilizado com agregação, o DISTINCT é aplicadoantes de agregar os dados Página 25
  26. 26. Resumo_Anotacoes_Certificacao_SCBCD_5.txt SELECT DISTINCT COUNT(c.address.zip) FROM Customers AS c WHEREc.address.zip LIKE 554% Efeito: conta apenas os registros com zip diferentes SELECT c FROM Customers AS c ORDER BY c.lastName SELECT c FROM Customers AS c WHERE c.address.city = Boston ANDc.address.state = MA ORDER BY c.lastName SELECT c FROM Customers AS c ORDER BY c.lastName DESC SELECT c FROM Customers AS c ORDER BY c.lastName ASC,c.firstName DESC Cuidado: SELECT addr.zip FROM Address AS addr ORDER BY addr.zip SELECT c.address FOR Customer AS c WHERE c.lastName =Smith ORDER BY c.address.zip ERRO: SELECT c FROM Customer AS c ORDER BYc.address.city Se a query retorna uma coleção, no campo orderby podem ser utilizados apenas campos basicos desta coleção ERRO: SELECT c.address.city FROM Customer AS c ORDER BYc.address.state O campo especificado em order by precisa estarsendo trazido no select SELECT cr.name, COUNT (res) FROM Cruise cr JOIN cr.reservationsres GROUP BY cr.name HAVING count(res) > 10 . Subqueries SELECT COUNT(res) FROM Reservation res WHERE res.amountPaid >(SELECT avg(r.amountPaid) FROM Reservation r) FROM Cruise cr WHERE 100000 < ( SELECT SUM(res.amountPaid) FROMcr.reservations res ) FROM Cruise cr WHERE 0 < ALL ( SELECT res.amountPaid fromcr.reservations res ) Efeito: Seleciona cruzeiros em que todas suas reservaspossuam valor de pagamento FROM Cruise cr WHERE 0 = ANY ( SELECT res.amountPaid fromcr.reservations res ) Efeito: Seleciona cruzeiros em que exista ao menos umareserva com valor zerado Obs.: SOME = ANY = NOT ALL FROM Cruise cr WHERE EXISTS (SELECT res FROM cr.reservationsWHERE res.amountPaid = 0) Obs.: Clausula EXISTS verifica se a subquery retornoualgum registro Efeito: Seleciona os cruseiros que tenham alguma reservasem pagamento . UPDATE e DELETE em lote UPDATE Reservation res SET res.amountPaid = (res.amountPaid +10) WHERE EXISTS ( SELECT c FROM res.customers c WHERE c.firstName =Bill AND c.lastName=Burke ) DELETE FROM Reservation res WHERE EXISTS ( SELECT c FROMres.customers c WHERE c.firstName = Bill AND c.lastName=Burke ) Página 26
  27. 27. Resumo_Anotacoes_Certificacao_SCBCD_5.txt- Scalar Native Queries Query createNativeQuery(String sql) . Usada para valores escalares, retorna um List de Object[] contendo osvalores- Simple Entity Native Queries Query createNativeQuery(String sql, Class entityClass) Query query = manager.createNativeQuery("SELECT p.phone_PK,p.phone_number, p.type FROM PHONE AS p", Phone.class); . Espera que os nomes dos campos retornados correspondam em nome e tipocom os atributos persistentes da entidade em questão, então a associação é feita automaticamente . É obrigatório retornar TODOS os atributos da entidade na query- Complex Native Queries Query createNativeQuery(String sql, String mappingName) @Entity @SqlResultSetMapping(name="customerAndCreditCardMapping", entities={ @EntityResult(entityClass=Customer.class), @EntityResult(entityClass=CreditCard.class, fields={@FieldResult(name="id",column="CC_ID"), @FieldResult(name="number", column="number")} )}) public class Customer {...} Query query = manager.createNativeQuery( "SELECT c.id, c.firstName,cc.id As CC_ID, cc.number FROM CUST_TABLE c, CREDIT_CARD_TABLE cc WHERE c.credit_card_id =cc.id", "customerAndCreditCardMapping"); . O mapeamento deve estar definido na entidade . Mapeamento via XML: <entity-mappings> <sql-result-set-mappingname="customerAndCreditCardMapping"> <entity-resultentity-class="com.titan.domain.Customer"/> <entity-resultentity-class="com.titan.domain.CreditCard"/> <field-result name="id" column="CC_ID"/> <field-result name="number"column="number"/> </entity-result> </sql-result-set-mapping> </entity-mappings> . Misturando resultado de Entidade e resultado Escalar: @SqlResultSetMapping(name="reservationCount", entities=@EntityResult(name="com.titan.domain.Cruise", fields=@FieldResult(name="id", column="id")), columns=@ColumnResult(name="resCount")) @Entity public class Cruise {...}-------------------------------------------------------------------------------- Página 27
  28. 28. Resumo_Anotacoes_Certificacao_SCBCD_5.txt------------------------------------------- Queryes Nomeadas . EJBQL Named Queryes @NamedQueries({ @NamedQuery(name="getAverageReservation", query="SELECT AVG( r.amountPaid) FROM Cruise Asc, JOIN c.reservations r WHERE c = :cruise"), @NamedQuery(name="findFullyPaidCruises", query="FROM Cruise cr WHERE 0 < ALL (SELECTres.amountPaid from cr.reservations res)") }) @Entity public class Cruise {...} Ou Via XML: <entity-mappings> <named-query name="getAverageReservation"> <query> SELECT AVG( r.amountPaid) FROMCruise As c JOIN c.reservations r WHERE c = :cruise </query> </named-query> </entity-mappings> . SQL Native Named Queryes @NamedNativeQuery(name="findCustAndCCNum", query="SELECT c.id, c.firstName, c.lastName, cc.numberAS CC_NUM FROM CUST_TABLE c, CREDIT_CARD_TABLE cc WHERE c.credit_card_id = cc.id", resultSetMapping="customerAndCCNumMapping") @SqlResultSetMapping(name="customerAndCCNumMapping", entities={@EntityResult(entityClass=Customer.class)}, columns={@ColumnResult(name="CC_NUM")} ) @Entity public class Customer {...} Ou via XML: <entity-mappings> <named-native-query name="findCustAndCCNum"result-set-mapping="customerAndCCNumMapping"> <query> SELECT c.id, c.firstName,c.lastName, cc.number AS CC_NUM FROM CUST_TABLE c, CREDIT_CARD_TABLE cc WHEREc.credit_card_id = cc.id </query> </named-native-query> </entity-mappings>- Sistema JMS . Provedor JMS Sistema de rotamento de mensagens . Clientes JMS Produtor (envia) e consumidor (recebe) . Características JMS - Assíncrono (cliente não espera resposta) - Não é propagada transação do produtor pro receptor - Não é propagada segurança nem credenciais do produtor proreceptor - Se o receptor estiver desconectado, o roteador garante a Página 28
  29. 29. Resumo_Anotacoes_Certificacao_SCBCD_5.txtentrega da mensagem - Ciclo de Vida: idêntico ao do Stateless Bean, também em poolde instâncias (também com @PostConstruct e @PreDestroy) @Resource(mappedName="ConnectionFactoryName") private ConnectionFactory connectionFactory; @Resource(mappedName="TopicName") private Topic topic; ... Connection connect = factory.createConnection( ); Session session = connect.createSession(true, 0); // 0 ->Session.AUTO_ACKNOWLEDGE MessageProducer producer = session.createProducer(topic); TextMessage textMsg = session.createTextMessage( ); textMsg.setText("my message"); producer.send(textMsg); connect.close( ); . ConnectionFactory Fornece uma factory para criar conexões JMS com um provedorespecífico . Connection Conexão efetica com o provedor JMS . Session - Sessão para agrupar ações de envio/recebimento de mensagens - Método createSession(boolean transacted, int acknowledgeMode)- muitos provedores utilizam true e 0 (Session.AUTO_ACKNOWLEDGE) por padrão, porém não é garantido - Obs.: O objeto session não é thread-safe, pode apenas umobjeto session JMS por Thread . Topic / Queue Nome do channel do Topic ou da Queue. - Topic . Tipo publish/subscribe . Muitos receptores (a mensagem é entregue àtodos que assinam) . Modelo push (o receptor é notificado damensagem) - Queue: . Tipo peer-to-peer . Um receptor (a mensagem é entregue apenas umavez, ao primeiro que receber) . Conceitualmente é pull (receptor solicita amensagem), mas também pode ser push, depende do fornecedor . Tipos de Mensagem - Sempre compostas por um Header e um Corpo: TextMessage textMsg = session.createTextMessage(); MapMessage mapMsg = session.createMapMessage(); ObjectMessage objMsg = session.createObjectMessage(); (outras...) - Exemplo de Header: textMessage.setJMSReplyTo(theAnotherQueue); . Cliente JMS Java SE ConnectionFactory factory = (ConnectionFactory)jndiContext.lookup("ConnectionFactoryNameGoesHere"); Topic topic = (Topic)jndiContext.lookup("TopicNameGoesHere"); Connection connect = factory.createConnection( ); Session session = connect.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageConsumer consumer = session.createConsumer(topic); Página 29
  30. 30. Resumo_Anotacoes_Certificacao_SCBCD_5.txt consumer.setMessageListener(this); //ou qualquer instancia queimplemente javax.jms.MessageListener connect.start( ); public void onMessage(Message message) { TextMessage textMsg = (TextMessage)message; String text = textMsg.getText(); }- Message Driven Beans . Bean especial para consumir mensagens . Não se deve utilizar um Session Bean para consumir mensagens (mas épossível, através dos métodos MessageConsumer.receive(), MessageConsumer.receive(long timeout) ouMessageConsumer.receiveNoWait() . Anotação @Target(TYPE) @Retention(RUNTIME) public @interface MessageDriven { String name() default ""; //nome do MDB Class messageListenerInterface default Object.class;//pode setar como javax.jms.MessageListener e não //implementar a interface explicitamente ActivationConfigProperty[] activationConfig() default{}; //configurações específicas de MDB String mappedName(); //se preferir pode especificar odestino aqui String description(); } . MessageDrivenContext - Extende o EJBContext, é semelhante ao SessionContext porém nãoadiciona nenhuma operação - Pode-se utilizar apenas os métodos transacionais. Os métodosde segurança lançam uma RuntimeException, pois na JMS não há propagação de segurança . Interface javax.jms.MessageListener Único método: public void onMessage(Message message) @MessageDriven( activationConfig={ @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty( propertyName="destinationName", propertyValue="jms/TitanQueue"), @ActivationConfigProperty( propertyName="messageSelector", propertyValue="MessageFormat = Version 3.4"), @ActivationConfigProperty( propertyName="acknowledgeMode", propertyValue="Auto-acknowledge") }) public class ReservationProcessorBean implementsjavax.jms.MessageListener { @Resource(mappedName="ConnectionFactory") private ConnectionFactory connectionFactory; public void onMessage(Message message) { try { MapMessage reservationMsg = (MapMessage)message; Página 30
  31. 31. Resumo_Anotacoes_Certificacao_SCBCD_5.txt int customerPk =reservationMsg.getInt("CustomerID"); int cruisePk =reservationMsg.getInt("CruiseID"); int cabinPk = reservationMsg.getInt("CabinID"); double price =reservationMsg.getDouble("Price"); } catch(Exception e) { throw new EJBException(e); } } } . Atributos ActivationConfigProperty - messageSelector Pode utilizar uma query sintaxe SQL para filtrar quaismensagens o bean vai consumir de acordo com propriedades setadas na mensagem - acknowledgeMode AUTO_ACKNOWLEDGE - é computado recebimento logo após amensagem ser entregue e processada DUPS_OK_ACKNOWLEDGE - é computado o recebimento em lote,de forma otimizada (o MDB precisa ter preparo para tratar mensagens duplicatas) - subscriptionDurability Durable - tolerantes à desconexão do container, amensagem é armazenada e entregue depois NonDurable - o contrário, qualquer mensagem recebidaenquanto desconectado será perdida . Descritor XML <enterprise-beans> <message-driven> <ejb-name>ReservationProcessorBean</ejb-name><ejb-class>com.titan.reservationprocessor.ReservationProcessorBean</ejb-class><messaging-type>javax.jms.MessageListener</messaging-type> <transaction-type>Container</transaction-type><message-destination-type>javax.jms.Queue</message-destination-type> <activation-config> <activation-property><activation-config-property-name>destinationType</activation-config-property-name><activation-config-property-value>javax.jms.Queue</activation-config-property-value> <activation-property> <activation-property><activation-config-property-name>destinationName</activation-config-property-name><activation-config-property-value>jms/TitanQueue</activation-config-property-value> <activation-property> <activation-property><activation-config-property-name>messageSelector</activation-config-property-name><activation-config-property-value>MessageFormat = Version3.4</activation-config-property-value> <activation-property> <activation-property> Página 31
  32. 32. Resumo_Anotacoes_Certificacao_SCBCD_5.txt<activation-config-property-name>acknowledgeMode</activation-config-property-name><activation-config-property-value>Auto-acknowledge</activation-config-property-value> <activation-property> </activation-config> </message-driven> </enterprise-beans></ejb-jar>--------------------------------------------------------------------------------------------------------------------------- Ouvindo um Timer @Stateless public class ShipMaintenanceBean implements ShipMaintenanceRemoteimplements javax.ejb.TimedObject { ... public void ejbTimeout(javax.ejb.Timer timer) { ... } } ou... @Stateless public class ShipMaintenanceBean implements ShipMaintenanceRemote { ... @Timeout public void myTimeout(javax.ejb.Timer timer) { ... } }- Criando um Timer . O próprio bean se registra para ouvir o timer . O timer pode ser criado em Stateless e MessageDriven beans . CUIDADO: não se deve criar timers em @PostConstruct nem @PreDestroy(são chamados para cada instância do pool), nem utilizando variáveis estáticas para verificar sejá foi criado (problema do cluster) . O timer deve ser criado apenas através de métodos de negócio invocadospelo cliente . Um timer service pode ser obtido através doEJBContext.getTimerService(), ou injetado pelo container: @Resource TimerService timerService; . Interface TimerService - public Timer createTimer(Date expiration, Serializable info) . Ação única . Expira na data especificada - public Timer createTimer(long duration, Serializable info) . Ação única . Expira depois de passado o tempo especificado emmilisegundos - public Timer createTimer(Date initialExpiration, longintervalDuration, Serializable info) . De intervalo . Expira na data especificada e subsequentemente a cadaintervalo especificado em intervalDuration - public Timer createTimer(long initialDuration, long Página 32
  33. 33. Resumo_Anotacoes_Certificacao_SCBCD_5.txtintervalDuration, Serializable info) . De intervalo . Expira depois de passado o tempo initialDuration esubsequentemente a cada intervalo especificado em intervalDuration - public Collection getTimers() . Retorna uma coleção contendo todos os timers agendadospara o beans em questão (apenas os timers do bean que chamou o método) Obs.: Todos os métodos TimerService lançam as exceções: . IllegalArgumentException: parâmetros negativos ou null . IllegalStateException: chamado de onde não é permitido . EJBException: encapsula qualquer outra exceção desistema . Interface Timer - public void cancel() Cancela o timer - public Serializable getInfo() Recupera o objeto passado na criação do timer - public Date getNextTimeout() Recupera a data em que ocorrerá a próxima expiração - public long getTimeRemaining() Recupera o tempo restante para a próxima expiração - public TimerHandle getHandle() Recupera uma referência serializável à instância destetimer Obs.: Todos os métodos Timer lançam as exceções: . NoSuchObjectLocalException: se invocado qualquermétodo em um timer de ação única expirado ou um timer cancelado . EJBException: encapsula qualquer outra exceção desistema . Reagendando temporizadores: precisa cancelar e criar um novo . Transação - É transacional no escopo da transação atual, ou seja, seocorrer rollback em um método que cria o timer, sua criação será desfeita - É boa prática o método de @Timeout ser transacionalRequiresNew, para assegurar que ele está no escopo transacional do container- Interceptors . Criando Classes Interceptadoras public class Profiler { @AroundInvoke public Object profile(InvocationContext invocation)throws Exception { long startTime = System.currentTimeMillis( ); try { return invocation.proceed( ); } finally { long endTime = System.currentTimeMillis() - startTime; System.out.println("Method " + Página 33
  34. 34. Resumo_Anotacoes_Certificacao_SCBCD_5.txtinvocation.getMethod( ) + " took " + endTime + " (ms)"); } } } . Interface InvocationContext public interface InvocationContext { public Object getTarget( ); public Method getMethod( ); public Object[] getParameters( ); public void setParameters(Object[] newArgs); public java.util.Map<String, Object> getContextData( ); public Object proceed( ) throws Exception; } . getTarget - retorna uma referência à instância do beanalvo . getMethod - retorna um objeto java.lang.reflect.Methoddo método que foi chamado . getParameters - retorna os parâmetros que foramenviados ao método . setParameters - modifica tais parâmetros (usar comcuidado) . getContextData - retorna um objeto Map que fica ativodurante toda a pilha de chamada, onde podemos compartilhar valores com outros interceptors . proceed - continua a pilha de chamada (próximointerceptor ou método original) . Aplicando Interceptors - Nível de Classe (intercepta todos os métodos do bean) @Stateless @Interceptors(Profiler.class) public class MyBean implements MyBeanRemote { ... } - Nível de Método (intercepta apenas o método anotado) @Stateless public class MyBean implements MyBeanRemote { @Interceptors(Profiler.class) public void myMethod() { ... } } - Aplicando via XML <ejb-jar> <assembly-descriptor> <interceptor-binding><ejb-name>TravelAgentBean</ejb-name> <!--<exclude-default-interceptors> e <exclude-class-interceptors> --><interceptor-class>com.titan.Profiler</interceptor-class><method-name>bookPassage</method-name> <method-params><method-param>com.titan.CreditCardDO</method-param><method-param>double</method-param> </method-params> Página 34

×