Your SlideShare is downloading. ×

Resumo Anotacoes Certificacao SCBCD 5

2,162

Published on

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

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,162
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
27
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  • 35. Resumo_Anotacoes_Certificacao_SCBCD_5.txt </interceptor-binding> </assembly-descriptor> </ejb-jar> . Obs: - <method-name> é utilizado apenas paraaplicar a nivel de método - <method-params> é útil se houveroverload no método especificado - Interceptors Padrão . Recebem um curinga (*). São aplicados para todos osmétodos de todos os beans do ejb-jar. <ejb-jar> <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name><interceptor-class>com.titan.Profiler</interceptor-class> </interceptor-binding> </assembly-descriptor> </ejb-jar> - Desativando Interceptors . @ExcludeDefaultInterceptors Ignora os interceptors-padrão da implantação . @ExcludeClassInterceptors Ignora os interceptors de nivel de classe dobean--------------------------------------------------------------------------------------------------------------------------- Interceptors e Injeção de Dependência (ENC) . O interceptor compartilha o mesmo JNDI ENC do bean que estáinterceptando . O EJBContext também é compartilhado . Injeção no Interceptor - Via Annotations public class AuditInterceptor { @Resource EJBContext ctx; @PersistenceContext(unitName="auditdb") EntityManager manager; @AroundInvoke public Object audit(InvocationContextinvocation) throws Exception { ... } } - Via XML <ejb-jar> <interceptors> <interceptor><interceptor-class>com.titan.interceptors.AuditInterceptor</interceptor-class> <around-invoke> Página 35
  • 36. Resumo_Anotacoes_Certificacao_SCBCD_5.txt<method-name>audit</method-name> </around-invoke> <persistence-context-ref><persistence-context-name>com.titan.interceptors.AuditInterceptor/manager</persistence-context-name><persistence-context-unit-name>auditdb</persistence-context-unit-name> <injection-target><injection-target-class>com.titan.interceptors.AuditInterceptor</injection-target-class><injection-target-name>manager</injection-target-name> </injection-target> </persistence-context-ref> </interceptor> </interceptors> </ejb-jar>--------------------------------------------------------------------------------------------------------------------------- Interceptors e Ciclo de Vida . Possuem o mesmo ciclo de vida do bean que interceptam . Podem interceptar métodos de callback do bean @<callback-annotation> void myMethod(InvocationContext ctx) {... } . Obs: - Não pode lançar exceções verificadas - Retorna void - Se o bean não tiver callback, a chamadactx.getMethod() retornará null . Para abortar a chamada do método original, basta lançar uma exceção(no lugar do método proceed) . Para lançar exceptions verificadas, elas precisam estar declaradas nainterface do bean--------------------------------------------------------------------------------------------------------------------------- Interceptor na Própria Classe Bean . É o último interceptador chamado na pilha até chegar ao método . É aplicado para todos os métodos da classe que reside @Stateless public class MySessionBean implements MySessionRemote { public void businessMethod( ) { ... } @AroundInvoke public Object beanClassInterceptor(InvocationContext ctx) { ... } }- Ordem de Execução de Interceptors 1 - Os default interceptors, declarados no deployment descriptor (xml) 2 - Os interceptors a nivel de classe, na ordem em que foram declaradosem @Interceptors (em seguida os do XML) 3 - Os interceptors a nivel do método específico (em seguida os do XML) 4 - O interceptor declarado no bean Página 36
  • 37. Resumo_Anotacoes_Certificacao_SCBCD_5.txt Obs: . Se um interceptor extende uma classe que também é interceptor,o @AroundInvoke da superclasse executa primeiro . Podemos utilizar uma tag <interceptor-order> para modificar aordem <assembly-descriptor> <interceptor-binding><ejb-name>org.jboss.tutorial.interceptor.bean.EmailSystemBean</ejb-name><method-name>sendBookingCancellationMessage</method-name> <interceptor-order><interceptor-class>org.jboss.tutorial.interceptor.bean.AccountsCancelInterceptor</interceptor-class><interceptor-class>org.jboss.tutorial.interceptor.bean.DefaultInterceptor</interceptor-class><interceptor-class>org.jboss.tutorial.interceptor.bean.OtherInterceptor</interceptor-class><interceptor-class>org.jboss.tutorial.interceptor.bean.TracingInterceptor</interceptor-class> </interceptor-order> </interceptor-binding> </assembly-descriptor>- JNDI ENC (Enterprise Naming Context) . É uma extensão do EJBContext para localizar recursos dentro de umespecífico EJB . Cada EJB possui seu próprio ENC, que não é compartilhado entre eles . Recursos disponíveis via JNDI ENC: - Outro EJB - Destino JMS - Connection Factories - Data Sources - Qualquer recurso JCA - UserTransaction - TimerService - org.omg.CORBA.ORB - Qualquer primitivo . Exemplo - Gravando ENC de outro EJB, via XML <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <ejb-local-ref><ejb-ref-name>ejb/ProcessPayment</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>com.titan.processpayment.ProcessPaymentLocal</local><ejb-link>ProcessPaymentBean</ejb-link> </ejb-local-ref> </session> </enterprise-beans> </ejb-jar> - Gravando ENC de outro EJB, via Annotations Página 37
  • 38. Resumo_Anotacoes_Certificacao_SCBCD_5.txt @Stateful @EJB(name="ejb/ProcessPayment", beanInterface=ProcessPaymentLocal.class, beanName="ProcessPaymentBean") public class TravelAgentBean implementsTravelAgentRemote { ... } - Obtendo o recurso do ENC . Via InitialContext javax.naming.InitialContext ctx = newInitialContext( ); ProcessPaymentLocal payment =(ProcessPaymentLocal)ctx.lookup("java:comp/env/ejb/ProcessPayment"); . Via EJBContext @Resource private SessionContext ejbContext; ... ProcessPaymentLocal payment =(ProcessPaymentLocal)ejbContext.lookup("ejb/ProcessPayment"); - Injeção de Dependência ENC . Via Annotations - No atributo: @EJB private ProcessPaymentLocal payment; - No método setter: @EJB public voidsetProcessPaymentLocal(ProcessPaymentLocal payment) { this.payment = payment; } . Via XML <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <ejb-local-ref><ejb-ref-name>ProcessPayment</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>com.titan.processpayment.ProcessPaymentLocal</local><ejb-link>ProcessPaymentBean</ejb-link><injection-target><injection-target-class>com.titan.travelagent.TravelAgentBean</injection-target-class><injection-target-name>payment</injection-target-name></injection-target> </ejb-local-ref> </session> </enterprise-beans> </ejb-jar> - Nome ENC padrão Página 38
  • 39. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . Via Annotations - Atributo "name" - Na falta do "name": . Em atributo <nome qualificado daclasse>/<nome do atributo> . Em setter <nome qualificado daclasse>/<nome da transformação setter em atributo> - Nenhum atributo da annotation é obrigatório - Não pode ocorrer injeção de um atributo e umsetter que resolvem o mesmo nome simultaneamente - No caso de herança, precisa definir o atributo"beanName" (annotation) ou <ejb-link> (xml)--------------------------------------------------------------------------------------------------------------------------- Tipos de Referencia . Referências EJB - Annotations public @interface EJB { String name( ) default ""; Class beanInterface( ) default Object.class; String beanName( ) default ""; String mappedName( ) default ""; } . name - nome que será gravano no ENC (relativoà java:comp/env) . beanInterface - interface a ser referenciada(distingue entre local e remote) . beanName - nome do ejb a ser referenciado(útil no caso de mais de um bean com a mesma interface, utiliza o dado @StateXXX.name() ou o <ejb-name>) . mappedName - recupera o recurso de um JNDIglobal . Obs.: - A nivel de classe: . é obrigatório "name" e"beanInterface" . para gravar mais de um EJB,utilizar @EJBs({ @EJB(...), @EJB(...) }) - A nivel de atributo ou setter: . nenhum dado é obrigatório - XML . Remoto <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <ejb-ref><ejb-ref-name>ejb/ProcessPaymentRemote</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><remote>com.titan.processpayment.ProcessPaymentRemote</remote> </ejb-ref> Página 39
  • 40. Resumo_Anotacoes_Certificacao_SCBCD_5.txt </session> </enterprise-beans> </ejb-jar> . Local <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <ejb-local-ref><ejb-ref-name>ejb/ProcessPaymentRemote</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>com.titan.processpayment.ProcessPaymentLocal</local> </ejb-local-ref> </session> </enterprise-beans> </ejb-jar> . Obs.: - Obrigatório: <ejb-ref-name>,<ejb-ref-type>, <remote> ou <local> - Opcional: <description>, <home>,<ejb-link>, <mapped-name>, <injection-target> - Obs. Gerais . Caso de nome duplicado em dois JARs no mesmo EAR: @EJB(beanName="inventory-ejb.jar#InventoryEJB") private InventoryLocal inventory; . Referências EntityManagerFactory - Annotations public @interface PersistenceUnit { String name( ) default ""; String unitName( ) default ""; } . name - nome a ser gravado no ENC . unitName - nome da unidade de persistencia(obrigatório apenas se o persistence.xml definir mais de uma) . Obs.: - A nivel de classe: . atributo "name" é obrigatório . para gravar mais de umPersistenceUnit, utilizar @PersistenceUnits({@PersistenceUnit(...), @PersistenceUnit(...) }) - A nivel de atributo ou setter: . apenas "unitName" que pode serobrigatório se houver mais de uma unidade definida no xml - XML <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <persistence-unit-ref> Página 40
  • 41. Resumo_Anotacoes_Certificacao_SCBCD_5.txt<persistence-unit-ref-name>persistence/TitanDB</persistence-unit-ref-name><persistence-unit-name>TitanDB</persistence-unit-name> </persistence-unit-ref> </session> </enterprise-beans> </ejb-jar> - Obs. Gerais . Caso de persistence-unit duplicado em dois JARs ou WARno mesmo EAR:@PersistenceUnit(unitName="inventory.jar#InventoryDB") private EntityManagerFactory inventoryFactory; . Injeção xml possível via <injection-target> . Referências EntityManager - Annotations public @interface PersistenceContext { String name( ) default ""; String unitName( ) default ""; PersistenceContextType type( ) defaultTRANSACTION; PersistenceProperty[] properties( ) default {}; } public enum PersistenceContextType { TRANSACTION, EXTENDED } public @interface PersistenceProperty { String name( ); String value( ); } . name - nome a ser gravado no ENC . unitName - nome da unidade de persistencia(obrigatório apenas se o persistence.xml definir mais de uma) . PersistenceContextType - opcional, o default éTRANSACTION . PersistenceProperty - opcional, específico defornecedor . Obs.: - A nivel de classe: . atributo "name" é obrigatório . para gravar mais de umPersistenceContext, utilizar @PersistenceContexts({@PersistenceContext(...), @PersistenceContext(...) }) - A nivel de atributo ou setter: . apenas "unitName" que pode serobrigatório se houver mais de uma unidade definida no xml - XML <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <persistence-context-ref><persistence-context-ref-name>persistence/TitanDB</persistence-context-ref-name> Página 41
  • 42. Resumo_Anotacoes_Certificacao_SCBCD_5.txt<persistence-unit-name>TitanDB</persistence-unit-name><persistence-context-type>EXTENDED</persistence-context-ref> <persistence-property><name>hibernate.show_sql</name><value>true</value> </persistence-property> </persistence-context-ref> </session> </enterprise-beans> </ejb-jar> - Obs. Gerais . Caso de persistence-unit duplicado em dois JARs ou WARno mesmo EAR:@PersistenceContext(unitName="inventory.jar#InventoryDB") private EntityManager inventoryManager; . Injeção xml possível via <injection-target> . Referências Recursos Reutilizáveis - Annotations public @interface Resource { String name( ) default ""; Class type( ) default Object.class; AuthenticationType authenticationType( ) defaultAuthenticationType.CONTAINER; boolean shareable( ) default true; String description( ) default ""; String mappedName( ) default ""; } public enum AuthenticationType { CONTAINER, APPLICATION } . name - nome a ser gravado no ENC . type - nome qualificado da classe do recurso . mappedName - associa a um recurso JNDI global . shareable - define se o recurso vai ter suaconexão compartilhada entre diferentes beans (padrão é true) . authenticationType - define que é responsávelpela autenticação no recurso em runtime . Obs.: - A nivel de classe: . atributos "name" e "type" sãoobrigatórios . para gravar mais de umResource, utilizar @Resources({ @Resource(...),@Resource(...) }) - A nivel de atributo ou setter: . apenas "mappedName" pode serobrigatório, se for um recurso JNDI global - XML <ejb-jar> <enterprise-beans> <session> Página 42
  • 43. Resumo_Anotacoes_Certificacao_SCBCD_5.txt<ejb-name>TravelAgentBean</ejb-name> <resource-ref><res-ref-name>jdbc/OracleDB</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth><mapped-name>java:/DefaultDS</mapped-name> </resource-ref> </session> </enterprise-beans> </ejb-jar> - Obs. Gerais . Injeção xml possível via <injection-target> - Referências Recursos de Objetos Administrados Ambiente Exemplo: EJBContext, SessionContext, UserTransaction <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <resource-env-ref><resource-env-ref-name>UserTransaction</res-ref-name><resource-env-ref-type>javax.transaction.UserTransaction</resource-env-ref-type> </resource-env-ref> </session> </enterprise-beans> </ejb-jar> - Referências Recursos de Constantes de Ambiente <ejb-jar> <enterprise-beans> <session><ejb-name>ProcessPaymentBean</ejb-name> <env-entry><env-entry-name>minCheckNumber</env-entry-name><env-entry-type>java.lang.Integer</env-entry-type><env-entry-value>2000</env-entry-value> </env-entry> </session> </enterprise-beans> </ejb-jar> . Obs: . Quase sempre utilizado em nível de atributo ousetter, pois não fornece metadados para inicializá-lo . Sempre primitivos e wrappers (java.lang) . Anotar o primitivo ou o setter não criaentrada no ENC, apenas puxa o valor, se houver - Referências Recursos de Destinos JMS <ejb-jar> Página 43
  • 44. Resumo_Anotacoes_Certificacao_SCBCD_5.txt <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <message-destination-ref><message-destination-ref-name>jms/TicketTopic</message-destination-ref-name><message-destination-type>javax.jms.Topic</message-destination-type><message-destination-usage>Produces</message-destination-usage><message-destination-link>Distributor</message-destination-link><mapped-name>topic/TicketTopic</mapped-name> </message-destination-ref> </session> </enterprise-beans> </ejb-jar> . Obs: . Obrigatório - <message-destination-ref-name>,<message-destination-type>, <message-destination-usage>] . Para utilizar um destino específico de bean<message-destination-link> é obrigatório o uso de XML, porém para os casos mais comunspode utilizar @Resource . O recurso sempre tem que ser obtido do JNDIglobal (mappedName) - Referências Web Services . N/A- Conceitos Transações ACID . Atomic Ou executa tudo com sucesso, ou não executa nada. .Consistent Os dados se mantém consistentes, com lógica para o modelo denegócio . Isolated Uma transação não influencia a outra . Durable Garantia que os dados são todos persistidos na base ao final datransação- Atributos de Transação public @interface TransactionAttribute { TransactionAttributeType value( ) defaultTransactionAttributeType.REQUIRED; } public enum TransactionAttributeType { MANDATORY, REQUIRED, REQUIRES_NEW, SUPPORTS, NOT_SUPPORTED, NEVER } . Via XML <ejb-jar> <assembly-descriptor> <container-transaction> Página 44
  • 45. Resumo_Anotacoes_Certificacao_SCBCD_5.txt <method> <ejb-name>TravelAgentEJB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>TravelAgentEJB</ejb-name> <method-name>bookPassage</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> . Obs. Gerais: - Por default, se não houver a anotação @TransactionAttribute, éadotado REQUIRED - Pode ser aplicado a nivel de classe, a nível de método ou comcuringa para todos os beans. Se aplicado a nivel de classe em conjunto com método, o do métodosobrescreve aquele método em particular . Tipos de Transação (ver imagens págs 266-268) - NOT_SUPPORTED A transação do chamador não é propagada, e o bean éexecutado sempre sem transação. - SUPPORTS Se o chamador tiver transação, ela é propagada. Casocontrário, o bean é executado sem transação. "Acompanha o chamador". - REQUIRED Se o chamador tiver transação, ela é propagada. Casocontrário, o bean cria uma transação própria. "Bean sempre tem transação". - REQUIRES_NEW O bean sempre cria uma transação própria,independentemente do chamador ter ou não transação. - MANDATORY Bean só executa se o chamador tiver transação. Casocontrário, lança EJBTransactionRequiredException. - NEVER Bean só executa se o chamador NÃO tiver transação. Casocontrário, lança EJBException. . Message-Driven Beans Podem ter apenas NOT_SUPPORTED (onMessage é executado semtransação), ou REQUIRED (onMessage é executado em uma própria transação) . Lembrete: Contexto de Persistência - TRANSACTION - é propagado junto com a transação - EXTENDED - dura o tempo de vida do Bean Statefull . Regras - Um bean com contexto TRANSACTION não pode invocar um bean comcontexto EXTENDED - Um bean com contexto EXTENDED pode invocar um bean comcontexto TRANSACTION (o contexto é propagado) - Um bean Statefull EXTENDED compartilha o contexto com outrobean Statefull EXTENDED apenas se o Página 45
  • 46. Resumo_Anotacoes_Certificacao_SCBCD_5.txt segundo bean foi injetado- Tipos de Problemas Comuns em Transações Concorrentes . Dirty reads . Repeatable reads . Phantom reads- Níveis de Isolamento . Read Uncommitted . Read Committed (é a que a especificação prevê) . Repeatable Read . Serializable- Optimistic Locking . É utilizado para garantir que não seja feito update concorrente em umobjeto e as modificações sejam sobrepostas no banco . É a técnica de realizar a leitura sendo "otimista", adotando queninguém alterou o registro. Então, no commit da transação, é verificado se este registro foi alterado ou não.Se sim, lança uma OptimisticLockException. . Para isso é criada uma nova coluna numérica na entidade, anotada com@Version, que será gerenciada pelo container . O @Version é incrementado automaticamente em cada update . Se você achar que este bloqueio irá ter um grande número de reversões,é mais performático utilizar o isolamento serializable- Locking Programático . É garantido apenas em entidades que possuem atributo @Version . Usa o método entityManager.lock(Object entity, LockModeType type) . O LockModeType pode ser: - READ - previne dirty-read e repetable-read - WRITE - idem READ, porém também realiza um incremento nacoluna @Version (SELECT ... FOR UPDATE)--------------------------------------------------------------------------------------------------------------------------- Bean Managed Transaction (BMT) . Quando a transação é gerenciada pelo própio cliente/bean, via código . Um cliente não-ejb pode demarcar uma transação obtendo oUserTransaction do container via JNDI . Cliente EJB BMT: @Stateless @TransactionManagement(TransactionManagerType.BEAN) public class HypotheticalBean implements HypotheticalLocal { ...} . Obtendo UserTransaction - Via injeção: @Resource private UserTransaction utx; - Via EJBContext (ou SessionContext) ejbContext.getUserTransaction(); . Delimitando a Transação: utx.begin(); ... utx.commit(); . Objeto UserTransaction public interface javax.transaction.UserTransaction { Página 46
  • 47. Resumo_Anotacoes_Certificacao_SCBCD_5.txt public abstract void begin( ) throwsIllegalStateException, SystemException; public abstract void commit( ) throwsIllegalStateException, SystemException, TransactionRolledbackException,HeuristicRollbackException, HeuristicMixedException; public abstract int getStatus( ); public abstract void rollback( ) throwsIllegalStateException, SecurityException, SystemException; public abstract void setRollbackOnly( ) throwsIllegalStateException, SystemException; public abstract void setTransactionTimeout(int seconds)throws SystemException; } . Obs. Gerais - Para beans Stateless, begin() e commit() precisam estar nomesmo método - Para beans Statefull, podem estar em métodos diferentes (nãousual) - Para beans MDB, há uma pequena diferença no uso de CMT e BMT: . CMT - a entrega da mensagem é incluída na transação . BMT - a entrega da mensagem não é incluída natransação (porém o JMS pode ainda contar com o acknowledge, pois se o onMessage lançar umaEJBException, o container tentará entregar novamente) - Não é permitido uso de begins e commits especificos de outrasAPIs (EntityManager, Connection, etc) - Beans CMT não podem utilizar UserTransaction--------------------------------------------------------------------------------------------------------------------------- Interface SessionSynchronization . Um bean statefull pode implementar a interface SessionSynchronization public interface javax.ejb.SessionSynchronization { public abstract void afterBegin( ) throwsRemoteException; public abstract void beforeCompletion( ) throwsRemoteException; public abstract void afterCompletion(boolean committed)throws RemoteException; } . Ela adiciona um novo estado de ciclo-de-vida (TransactionalMethod-Ready), incluindo mais três métodos de callback, chamados quando um contexto de transação é criado no beanstatefull - afterBegin Invocado quando o contexto é criado, ou seja, um métodotransacional é invocado e cria um novo contexto transacional - beforeCompletion Invocado se a transação for comitada - afterCompletion(boolean commited) Invocado quando a transação termina, recebendo umboolean indicando se foi comitada ou não . Obs. Gerais - Em um bean statefull, enquanto um contexto transacional não écompletado, é proibido iniciar um novo Página 47
  • 48. Resumo_Anotacoes_Certificacao_SCBCD_5.txt contexto transacional (RequiresNew, NotSupported ou Never) namesma instância do bean, e também é proibido chamar o método @Remove sem terminar o contextotransacional (nos dois casos é lançada uma exceção) - Lembrete: um bean statefull com contexto de persistênciaEXTENDED pode interagir com o EntityManager mesmo fora de uma transação, enfileirando as ações até que hajauma transação (isso pode ser usado em conjunto com o Optimistic-Locking para não manter transações vivas pormuito tempo durante diferentes chamadas de métodos no bean statefull), ou seja, interagimos à vontade sem contextotransacional, e utilizamos um único método transacional que efetua o "flush" no EntityManager - Lembrete: um bean com contexto de persistência EXTENDEDutilizando um EntityManager em um método fora de um escopo transacional não pode propagar seu contexto depersistência para um bean de contexto TRANSACTION, para isso precisamos tornar esse segundo bean em statefull e utilizarnele um contexto EXTENDED--------------------------------------------------------------------------------------------------------------------------- Exceções e Transações . Exceções de Sistema - java.lang.RuntimeException - javax.ejb.EJBException - javax.rmi.RemoteException - Comportamento: . container empacota a exceção: - se o cliente propagou a transação, éempacotada em EJBTransactionRolledbackException - caso contrário, é empacotada em EJBException . container reverte a transação . container descarta a instancia do bean (fica prontapara coleta de lixo) . container registra log - Obs: . se o bean for statefull, o impacto no cliente ésevero: qualquer invocação de método subsequente à exceção retorna uma NoSuchEJBException (subclasse deRuntimeException) . se o bean for MDB, se trata transações como BMT, amensagem poderia não ser entregue novamente (acknowledge) . Exceções de Aplicativo - Qualquer outro tipo de exception de negócio - Comportamento: . container não empacota a exception, repassa ao clienteda forma que foi lançada . antes de devolver ao cliente, se a transação é CMT efoi criada pelo bean, o container tenta comitar . não reverte a transação nem mata o bean . se é um MDB, adotar como "cliente" do método onMessageo adaptador JCA do recurso JMS . @ApplicationException @ApplicationException(rollback=true) public class PaymentException extends java.lang.Exception { ...} Página 48
  • 49. Resumo_Anotacoes_Certificacao_SCBCD_5.txt - Com essa anotação podemos fazer com que uma exceção deaplicativo reverta a transação - Podemos anotar exceções de sistema e fazer com que elas secomportem como exceções de aplicativo - Atributo roolback define se queremos reverter a transação - Exemplo de definição em XML: <ejb-jar> <assembly-descriptor> <application-exception><exception-class>java.sql.SQLException</exception-class> <rollback>true</rollback> </application-exception> </assembly-descriptor> </ejb-jar>- Conceitos Gerais . Autenticação Se o usuário é quem diz ser (validação username e senha) . Autorização Se um usuário, já autenticado, tem direito de acessar talrecurso . Confidencialidade e Integridade Se os dados trocados não vão ser lidos ou alterados durante otráfego na rede . Obs. Gerais: - Beans de entidade ainda não suportam recursos de segurança,devemos utilizar os específicos do respectivo RDBMS- Auntenticação . Via JNDI ou JAAS - JNDI: properties.put(Context.SECURITY_PRINCIPAL, userName); properties.put(Context.SECURITY_CREDENTIALS, userPassword); InitialContext ctx = new InitialContext(properties); Object ref = jndiContext.lookup("TravelAgent"); TravelAgentRemote remote = (TravelAgentRemote) PortableRemoteObject.narrow(ref, TravelAgentRemote.class);- Autorização . @RolesAllowed(String[] values) - Especifica as roles que podem acessar o recurso. Pode serutilizado a nivel de bean ou de método . @PermitAll - Permite acesso a qualquer usuário autenticado . Especificando via XML <ejb-jar version="3.0"> <assembly-descriptor> <security-role> <description>This role represents anauthorized merchant</description><role-name>AUTHORIZED_MERCHANT</role-name> </security-role> Página 49
  • 50. Resumo_Anotacoes_Certificacao_SCBCD_5.txt <method-permission><role-name>AUTHORIZED_MERCHANT</role-name> <method><ejb-name>ProcessPaymentBean</ejb-name><method-name>byCredit</method-name> </method> </method-permission> <method-permission><role-name>CHECK_FRAUD_ENABLED</role-name><role-name>AUTHORIZED_MERCHANT</role-name> <method><ejb-name>ProcessPaymentBean</ejb-name> <method-name>*</method-name><method-intf>Remote</method-intf> </method> </method-permission> <method-permission> <unchecked/> <method><ejb-name>ProcessPaymentBean</ejb-name><method-name>byCheck</method-name> <method-params><method-param>com.titan.domain.Customer</method-param><method-param>com.titan.processpayment.CheckDO</method-param><method-param>double</method-param> </method-params> </method> </method-permission> </assembly-descriptor> </ejb-jar> - Obs. do mapeamento via XML . A anotação @PermitAll é o equivalente doelemento <unchecked/> . No <method-name> podemos utilizar o curinga(*), que autoriza a nível do bean (todos métodos) . Para métodos em overload, existe o elemento<method-params>, que se não for especificado, aplica a autorização para todas as assinaturassobrecarregadas . Por default, a autorização se aplica a todasinterfaces de negócio do bean . Utilizar o elemento <method-intf> para definira interface de negócio que será aplicada a autorização (Remote, Local,ServiceEndpoint, Home e LocalHome) . @DenyAll - Bloqueia o acesso ao recurso (nível de método ou de bean) - É mais utilizada via XML, com o elemento <exclude-list>: <ejb-jar> <assembly-descriptor> <exclude-list> <method> <ejb-name>ProcessPaymentBean</ejb-name> Página 50
  • 51. Resumo_Anotacoes_Certificacao_SCBCD_5.txt <method-name>byCash</method-name> </method> </exclude-list> </assembly-descriptor> </ejb-jar> . @RunAs(String value) - Determina uma role a qual o EJB utilizará para invocar outrosbeans eventualmente protegidos, sempre a nível de bean @Stateful @RunAs("AUTHORIZED_MERCHANT") public class TravelAgentBean implementsTravelAgentRemote { ... } - Via XML: <ejb-jar> <enterprise-beans> <session><ejb-name>TravelAgentBean</ejb-name> <security-identity> <run-as><role-name>AUTHORIZED_MERCHANT</role-name> </run-as> </security-identity> </session> </enterprise-beans> </ejb-jar> - Para utilizar a mesma role do chamador, utilizar o elemento<user-caller-identity/>: <enterprise-beans> <session> <ejb-name>EmployeeService</ejb-name> <security-identity> <user-caller-identity/> </security-identity> </session> </enterprise-beans>--------------------------------------------------------------------------------------------------------------------------- Segurança Programática . Existem dois métodos do EJBContext: Principal getCallerPrincipal(); boolean isUserInRole(String roleName); . getCallerPrincipal - Exemplo de uso: @Stateless public class ProcessPaymentBean implementsProcessPaymentLocal { @Resource SessionContext ctx; ... Página 51
  • 52. Resumo_Anotacoes_Certificacao_SCBCD_5.txt private boolean process() { Principal caller =ctx.getCallerPrincipal(); String username = caller.getName( ); ... } } . isUserInRole - Precisa usar uma role presente na anotação @DeclaredRoles,para que através da anotação, o container verifique se a role existe declarada no sistema - Exemplo de uso: @Stateless @DeclareRoles("JUNIOR_TRAVEL_AGENT") public class ProcessPaymentBean implementsProcessPaymentLocal { @Resource SessionContext ctx; private boolean process() { if (ctx.isCallerInRole("JUNIOR_TRAVEL_AGENT") ) { //do something } } } - Correspondente @DeclaredRoles em XML: <ejb-jar version="3.0"> <enterprise-beans> <session><ejb-name>ProcessPaymentBean</ejb-name> <security-role-ref><role-name>JUNIOR_TRAVEL_AGENT</role-name> </security-role-ref> </session> </enterprise-beans> </ejb-jar> . Obs: - Podemos utilizar roles virtuais nobean e mapear para uma role real: <security-role-ref><role-name>JUNIOR_AGENT</role-name> <!-- nome usado no bean --><role-link>JUNIOR_TRAVEL_AGENT</role-link> <!-- nome real da role --> </security-role-ref>- Conceitos Gerais . JAX-RPC API para criação de WebServices (Java API for XML-based RPC).Utiliza muitos descritores e arquivos mapeamento . JAX-WS Melhoria da API JAX-RPC (Java API for XML-based WebServices).Encapsula os descritores com uso de annotations- Expondo um WebService (JAX-WS) Página 52
  • 53. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . Utilizando o Próprio Bean @Stateless @WebService public class TravelAgentBean implements TravelAgentBeanRemote { @WebMethod public String makeReservation(int cruiseId, int cabinId, intcustomerId, double price) { ... } } . Utilizando uma Interface Endpoint @WebService public interface TravelAgentEndpoint { public String makeReservation(int cruiseId, int cabinId, intcustomerId, double price); } @WebService(endpointInterface ="com.titan.webservice.TravelAgentEndpoint") public class TravelAgentBean implements TravelAgentEndpoint { ... } . Regras: - Se nenhum método estiver anotado com WebMethod, todosos métodos do bean serão expostos como WebService - Se houver ao menos um método anotado, serão expostosapenas os métodos anotados - Ao utilizar uma interface de endpoint, todos osmétodos da interface serão expostos . @WebService public @interface WebService { String name( ) default ""; String targetNamespace( ) default ""; String serviceName( ) default ""; String wsdlLocation( ) default ""; String portName( ) default ""; String endpointInterface( ) default ""; } - name: nome do webservice gerado (nome doportType), o default é o nome da classe/interface - targetNamespace: namespace dos elementos xmlgerados para esse serviço, o default é o nome do package da classe/interface - wsdlLocation: usado para mapear o servico a umwsdl já existente - portName: wsdl port a ser usado - endpointInterface: para exposição viainterface endpoint . @WebMethod public @interface WebMethod { String operationName( ) default ""; String action( ) default ""; } - operationName: nome da operação no wsdl Página 53
  • 54. Resumo_Anotacoes_Certificacao_SCBCD_5.txt . @SOAPBinding public @interface SOAPBinding { public enum Style {DOCUMENT, RPC}; public enum Use {LITERAL, ENCODED}; public enum ParameterStyle {BARE, WRAPPED} Style style( ) default Style.DOCUMENT; Use use( ) default Use.LITERAL; ParameterStyle parameterStyle( ) defaultParameterStyle.WRAPPED; } - RPC + LITERAL: cada parametro é mapeado parawsdl:part, que contém o seu schema - DOCUMENT + LITERAL + BARE: a mensagem inteiraé um único schema - DOCUMENT + LITERAL + WRAPPED: a mensagem é umschema, que é envolvido sob um elemento root com o mesmo nome da operação . @WebParam public @interface WebParam { public enum Mode {IN, OUT, INOUT}; String name( ) default ""; String targetNamespace( ) default ""; Mode mode( ) default Mode.IN; boolean header( ) default false; } . @WebResult public @interface WebResult { String name( ) default ""; String targetNamespace( ) default ""; } . @OneWay - Pré-define que a operação não retorna nenhum valor,podendo otimizar a implementação através de uma chamada assíncrona (o wsdl não possui o elemento<output>)- Interceptors . Mesmo ciclo de vida do bean . Acessa mesmos contextos do bean . Pode usar contexto de persistencia extended apenas se interceptar beanstatefull . Não deve ser declarado static nem final . Apenas a nivel de classe pode interceptar callbacks do bean . O bean não precisa ter o callback declarado para isso (getMethodretornará null) . No caso de um método AroundInvoke overrideado, o pai não é executado,e o filho é executado apenas se tiver a anotação também . Pode ter mais de um AroundInvoke na mesma classe (tanto interceptorquanto bean) . Os interceptadores de callback podem ter apenas um de cada tipo (poremno caso de herança de interceptors, usa a mesma regra) . Não pode ser um método da interface de negocio do bean . Não pode lançar uma application-exception que não seja declarada nainterface de negocio . Assinatura: - Interceptor de método: <qualquer mod acesso> Object<METODO>(InvocationContext) Página 54
  • 55. Resumo_Anotacoes_Certificacao_SCBCD_5.txt - Interceptor de callback: <qualquer mod acesso> void<METODO>(InvocationContext)------------------------------------------------------------------------------------------------------- JNDI ENC e Injeção . Um único ENC para cada bean (compartilhado apenas com seusinterceptors) . O lookup sempre retorna uma nova instância do recurso, exceto para: - String - Objeto singleton - Objeto definido para ser compartilhavel (ex. java:comp/ORB) . O campo/método que recebe a injeção não pode ser static, e se forcampo não pode ser final . Nome JNDI injetado a método segue a nomenclatura JavaBeans do método,independente do campo . Nomenclatura:java:comp/env/NOME_QUALIFICADO_CLASSE/NOME_JAVABEAN_ATRIBUTO_OU_METODO . No caso de herança, podem ser anotados campos na superclasse paraserem injetados, porém as regras de override se aplicam (a injeção pode ser modificada ou anuladana classe filha) . Pode ser injetado um bean JEE 2.1, utilizando sua interface Home . Mesmo campos que não são herdados podem pedir injeção . Quando o tipo de referência de um campo não consegue especificar otipo de recurso, é preciso especificar o tipo na anotação . A injeção é feita depois do EJBContext ser configurado------------------------------------------------------------------------------------------------------- Timer Service . Não pode ser criado para bean STATEFULL . O timer sobrevive a container-crash, server-shutdown, etc . É transacional no escopo da transação corrente (tanto a criação quantoo método de ejbTimeout) . Bean pode conter apenas um método de timeout . O método de timeout não deve ser static nem final . Não deve lançar application-exception . Devido ao trabalho do container, o metodo talvez não seja executadoexatamente na hora certa . É executado pelo container, portanto não há contexto de segurança dechamador associado (o metodo getCallerPrincipal retorna um principal não-autenticado) . Podem ser comparados entre si com o método equals (o operador == nãofunciona) . A referencia retornada por getHandle() é local, e não deve ser passadopor uma chamada remota . No caso de herança, o metodo de timeout pode ser definido em qualquersuperclasse do bean . Assinatura: - Usando anottation: <qualquer mod acesso> void <METODO>(Timer) - Implementando interface TimedObject: public voidejbTimeout(Timer timer)------------------------------------------------------------------------------------------------------- EJBContext . getTimerService não pode ser chamado em bean statefull(IllegalStateException)- SessionContext . setRollbackOnly e getRollbackOnly podem ser chamados apenas em beansCMT (IllegalStateException) . getUserTransaction pode ser chamado apenas em bean BMT Página 55
  • 56. Resumo_Anotacoes_Certificacao_SCBCD_5.txt(IllegalStateException) . getMessageContext pode ser chamado apenas em bean que implementa umendpoint WS . getBusinessObject pode ser chamado apenas em bean que utilizainterface EJB 3.0 . getEJBObject, getEJBLocalObject, getEJBHome, getEJBLocalHome pode serchamado apenas por bean que implementa a respectiva interface . O método de lookup do EJBContext já encapsula o InitialContext e onarrow- Interoperabilidade EJB 2.1 e EJB 3.0 . Cliente 3.0 / Bean 2.1: - Injeta a Home, e chama o método create(), depois utiliza areferência normalmente . Cliente 2.1 / Bean 3.0 - Adiciona a Home ao bean 3.0, faz lookup, chama create() eutiliza a referencia normalmente . Cliente 2.1 / EntityManager - Faz lookup ao EntityManager e utiliza normalmente------------------------------------------------------------------------------------------------------- Statefull vs Stateless . Apassivação de bean statefull: - apenas se ele não tiver em uma transação - se tiver contexto extendido, precisa: todas entities seremserializáveis e EntityManager ser serializável- Remote vs Local Interfaces . Requerimentos para Business Interfaces - a interface não pode extender EJBObject ou EJBLocalObject - não deve declarar throws RemoteException (apenas se ainterface extender java.rmi.Remote) - se um bean implementa uma interface, ela é por padrão local sefor omitida a anotação - não pode anotar uma mesma interface como @Local e @Remotesimultaneamente - se houver a definição da interface via metadata, o bean nãoprecisa implementar literalmente a interface (porém é uma boa prática)- Session Bean . Precisa ser public . Não pode ser final nem abstract . Precisa de construtor sem argumentos . Não pode definir método finalize() . Precisa implementar toda a interface de negócio . Precisa ser uma Top Level Class (oposto de inner-class) . Não pode ter uma superclasse que é session bean . Precisam ser anotadas ou declaradas (apenas implementar SessionBeannão vale) . Bean statefull não precisa implementar Serializable (container deveprover apassivação mesmo se não for) . Apenas statefull pode implementar SessionSynchronization interface- Callbacks . Se PrePassivate ou PostActivate for definido para bean stateless, seráignorado . Eles executam em um contexto não especificado de transação e segurança . Se o bean implementa a interface SessionBean, as anotação sãopermitidas somente aos métodos reais . Método @Remove fornece opção booleana retainIfException() que nãoremove se ocorrer Página 56
  • 57. Resumo_Anotacoes_Certificacao_SCBCD_5.txt uma application-exception- Message Driven Bean . Precisa ser public . Não pode ser final nem abstract . Precisa de construtor sem argumentos . Não pode definir método finalize() . Precisa ser uma Top Level Class (oposto de inner-class) . Pode implementar ejbCreate . Precisa implementar MessageDriven interface, porém é obrigatório aanotação @MessageDriven ou então a declaração no ejb-jar.xml . Pode ter mais de um método onMessage, porém o JCA determinará qualserá chamado (apenas um) . As mensagens podem vir fora de ordem . Em caso de herança, pode definir os métodos de callback em qualquersuperclasse . Acknowledge nunca pode ser setado programaticamente pela api JMS: - Se o bean for CMT: ocorre automaticamente pelo container, nahora do commit - Se o bean for BMT: o acknowledge não fará parte da transação,onde poderá ser setado: . AUTO_ACKNOWLEDGE (padrão) . DUPS_OK_ACKNOWLEDGE------------------------------------------------------------------------------------------------------- Persistence Entities . Precisa ter anotação @Entity ou declarada no xml . Precisa de construtor sem argumentos (public ou protected) . Precisa ser uma Top Level Class (oposto de inner-class) . Precisa ter uma primary key - @Id . Não pode ser final . Atributos persistentes não podem ser final . Atributos persistentes não podem ser public (não devem ser acessadosdiretamente por clientes da classe) . Para ser passada por invocação remota, precisa implementarSerializable . Entities podem ser concretas ou abstratas . Entities podem extender entities e non-entities . Non-entities podem extender entities . Não pode haver anotações de mapeamento em atributos / getterstransientes . Não pode misturar definição field-based com property-based na mesmaentitdade (comportamento indefinido) . Se usado acesso property-based, o provider pode executar validaçõesque estejam no método . Coleções podem ser: Collection, Set, List, Map (e suas variaçõesgenerics) . Erro de base causa rollback e lança uma PersistenceException------------------------------------------------------------------------------------------------------- Transações . BMT: - Bean stateless precisa terminar a transação antes de retornaro método (ou do último interceptor), caso contrário ocorre: log + rollback +EJBException + fim da instancia - Bean statefull pode manter a mesma transação entre chamadas demétodos diferentes - Bean BMT não deve usar EJBContext.setRollbackOnly nemEJBContext.getRollbackOnly (para isso servem UserTransaction.getStatus e UserTransaction.rollback) Página 57
  • 58. Resumo_Anotacoes_Certificacao_SCBCD_5.txt - O container deve disponibilizar UserTransaction para: . Interfaces de negócio (ou superinterfaces de negócio) . Método message-listener . Interceptor . Timeout - Não deve usar métodos de transação de APIs específicas dosrecursos (apenas EntityManager) . CMT: - Não deve usar métodos de transação de APIs específicas dosrecursos e não pode obter uma UserTransaction - Bean MDB: o contexto da transação é criado antes da entrega damensagem - Apenas o Bean Provider deve especificar os metadados de CMT - Quando uma transação não propaga (devido ao atributo detransação), a do cliente apenas fica suspensa, retornando na volta do método - Restrições, pode apenas: . onMessage - REQUIRED, NOT_SUPPORTED . @Timeout - REQUIRED, REQUIRES_NEW, NOT_SUPPORTED . SessionSyncronization - REQUIRED, REQUIRES_NEW,MANDATORY - Especificação do atributos de transação: . Nível de classe: é aplicado a todos os métodos dainterface de negócio . Nível de Método: sobrescreve para aquele método . Superclasse: aplica aos métodos da int. de negóciodefinidos na superclasse, podendo ser sobrescritos pela subclasse - Se chamar setRollbackOnly, o container processa normalmente ométodo e efetua o rollback depois do retorno ser enviado ao cliente - Ocorre IllegalStateException se chamar setRollbackOnly ougetRollbackOnly para SUPPORTS, NOT_SUPPORTED e NEVER- SessionSynchronization . Apenas para bean Statefull e CMT . afterBegin - Ocorre antes da primeira chamada transacional - Já está no escopo da transação . beforeCompletion - Ocorre no fim do método quando é para comitar, mas antes docommit efetivo da transação - Ainda está no escopo da transação - Chamar setRollbackOnly consegue reverter a transação . afterCompletion - Ocorre no fim do método sempre, enviando booleano falando deteve commit ou rollback------------------------------------------------------------------------------------------------------- Exception Handling . Aplication-exception: - Pode ser filha de Exception ou RuntimeException - Não pode ser filha de java.rmi.RemoteException - Propagada ao cliente sem mudanças - Não causa rollback (ao menos que seja filha deRuntimeException e não esteja anotada) . System-exception - Qualquer java.rmi.RemoteException ou RuntimeException nãoanotada - Causa rollback da exceção - Container: loga + lança EJBException + mata instancia Página 58

×