217
Curso: Persistência em Java com Curso: Persistência em Java com Hibernate Hibernate Instrutor: Fabrício Lemos 23/04/2007

Curso De Hibernate 3

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Curso De Hibernate 3

Curso: Persistência em Java com Curso: Persistência em Java com HibernateHibernate

Instrutor: Fabrício Lemos 23/04/2007

Page 2: Curso De Hibernate 3

Persistência

É um tópico vital para o desenvolvimento de aplicações

Quase todas as aplicações necessitam que dados sejam persistidos

Necessidades Armazenamento Busca Organização Compartilhamento dos dados

Page 3: Curso De Hibernate 3

Persistência

Necessidades Integridade dos dados Controle de concorrência

Performance e a escalabilidade são fortemente afetadas pela estratégia de acesso a dados escolhida

Page 4: Curso De Hibernate 3

Banco de Dados Relacionais

Geralmente são utilizados banco de dados SQL Flexível Robusto Eficiente Confiável Maneira mais utilizada e conhecida de armazenar

dados

Page 5: Curso De Hibernate 3

Banco de Dados Relacionais

Dados são armazenados de forma independente Independência de linguagem Independência de aplicação

Os dados geralmente possuem longevidade maior do que as aplicações que os acessam

A utilização de algum framework não elimina a necessidade de conhecimento de SQL e do modelo relacional

Page 6: Curso De Hibernate 3

Persistindo dados com Java

Realizado através da API Java Database Connectivity (JDBC)

Tarefas de baixo nível Preparar consultas Associar parâmetros Executar a consulta Percorrer e retornar o resultado

Tarefas de alto nível Salvar e recuperar objetos

Page 7: Curso De Hibernate 3

Persistindo objetos com Java(ou qualquer outra linguagem OO)

Linguagem orientada a objetos Deve-se poder armazenar o estado de um objeto,

mesmo após o objeto ser destruído Deve ser possível criar um novo objeto com o

mesmo estado do anterior Operações não devem ser limitadas a um único

objeto Associações devem ser salvas

Page 8: Curso De Hibernate 3

Persistindo objetos com Java

A aplicação deve trabalhar diretamente com objetos, ao invés de linhas e colunas da base de dados

Lógica de negócio deve ser implementada na aplicação, utilizando-se Java, e não diretamente na base de dados Limitar o uso de stored procedures

Conceitos da Orientação a Objetos não devem ser restringidos pela solução adotada

Page 9: Curso De Hibernate 3

Diferença dos Paradigmas: OO/Relacional

Granularidade Objetos de baixa granularidade podem ser persistidos

em tabelas de grande granularidade ou vice-versa Uma tabela armazena diversos tipos de objetos Um objeto é armazenado em diversas tabelas

Herança Modelo relacional não possui o conceito de herança

Page 10: Curso De Hibernate 3

Diferença dos Paradigmas

Polimorfismo Necessidade de um objeto referenciar outros através

de superclasses Uma referência pode estar associada o objetos de

tipos diferentes Chaves estrangeiras referenciam uma tabela

específica

Page 11: Curso De Hibernate 3

Diferença dos Paradigmas OO/Relacional

Identidade dos objetos Java

Operador == Método equals()

Banco de dados Chave primária Atualização de algum atributo que faz parte da chave

requer que outras tabelas sejam atualizadas

Page 12: Curso De Hibernate 3

Diferença dos Paradigmas OO/Relacional

Associações OO possui associações unidirecionais e bidirecionais Junções de tabelas e projeções não possuem o

conceito de “direção” de uma associação Associações em OO podem ser do tipo many-to-many Associações entre tabelas só podem ser one-to-many e

one-to-one Necessidade de criar uma tabela de relacionamento para

associações many-to-many Tabela não presente no modelo do domínio da aplicação

Page 13: Curso De Hibernate 3

Diferença dos Paradigmas: Custo

Necessário escrever muito código para (tentar) contornar o problema

Código se torna repetitivo e de difícil manutenção A escrita de código SQL pode tornar a aplicação

dependente do banco de dados Modelagem dos objetos fica prejudicada Outras camada ficam fortemente acopladas à

Camada de Persistência Produtividade pode ser fortemente afetada

Page 14: Curso De Hibernate 3

Estratégias de Persistência

JDBC e SQL Faz parte da plataforma Java Necessário escrever bastante código de baixo nível

Stored Procedures Lógica de negócio sai da aplicação e vai para a base

de dados Perde-se a portabilidade

Page 15: Curso De Hibernate 3

Estratégias de Persistência

Framework corporativo Necessário grande esforço da empresa Demora-se muito para que a solução implementada

atinga maturidade Documentação muitas vezes é esquecida Falta de suporte

Page 16: Curso De Hibernate 3

Estratégias de Persistência

Java Persistence API (JPA) Especificação elaborada pelo Java Community

Process para persistência em Java Baseou-se em diversas soluções existentes Frameworks existentes passaram a implementar a

especificação Recursos são um sub-conjunto dos encontrados nos

frameworks que a implementam Atualizações são lentas e burocráticas

Page 17: Curso De Hibernate 3

Estratégias de Persistência

Frameworks de terceiros TopLink

Framework de persistência Objeto/Relacional Desenvolvido pela Oracle Gratuito para avaliação e nas fases de desenvolvimento

Hibernate

Page 18: Curso De Hibernate 3

Hibernate

Framework de mapeamento Objeto-Relacional Preenche a lacuna entre a base de dados

relacional e a aplicação orientada a objetos Framework de persistência Java mais utilizado e

documentado Mantido pela Jboss sob a licensa LGPL Suporta classes desenvolvidas com agregação,

herança, polimorfismo, composição e coleções

Page 19: Curso De Hibernate 3

Hibernate

Permite a escrita de consultas tanto através de uma linguagem própria (HQL) como também através de SQL

Framework não intrusivo Não restringe a arquitetura da aplicação

Implementa a especificação Java Persistence API Grande e ativa comunidade

Mais de 25 mil desenvolvedores registrados nos foruns oficiais

Page 20: Curso De Hibernate 3

Mapeamento Objeto Relacional

Permite a persistência de objetos em tabelas de uma base de dados relacional

Automática e Transparente Utiliza metadados para descrever o

relacionamento entre os objetos e a base de dados XML Xdoclet Annotations

Page 21: Curso De Hibernate 3

Mapeamento Objeto Relacional

O SQL é gerado automaticamente a partir dos metadados

A escrita e manutenção de metadados necessita de esforço nas etapas de implementação Esforço bem menor do que o necessário para fazer a

conversão manualmente A conversão entre os tipos de representação pode

trazer perca de performance Ferramentas maduras otimizam a conversão em

diversos pontos

Page 22: Curso De Hibernate 3

Mapeamento Objeto Relacional

Possui quatro partes principais API para realização de operações básicas (CRUD) Linguagem ou API para a realização de consultas Maneira para a especificação de metadados Técnicas de otimização

Dirty checking Carregamento tardio (lazy association fetching)

Page 23: Curso De Hibernate 3

Mapeamento Objeto Relacional: Vantagens

Produtividade Elimina a necessidade de escrita de grande parte do

código relativo a persistência Maior tempo disponível para implementar a lógica da

aplicação Manutenibilidade

Menos código Maior entendimento da aplicação Camada de abstração Facilita a refatoração

Page 24: Curso De Hibernate 3

Vantagens Performance

Tarefas manuais nem sempre tem performance melhor do que tarefas automatizadas

Considerando limitações de custo e tempo Frameworks maduros são bastantes otimizados Com o aumento de produtividade, você pode dedicar

mais tempo para resolver possíveis gargalos Portabilidade

Independência nem sempre é algo simples de ser alcançado, mesmo em aplicações Java

Suporte a diversos tipos de banco de dados

Page 25: Curso De Hibernate 3

Hibernate: Módulos

Hibernate Core Contém os serviços básicos Metadados escritos em XML Consultas

HQL: Hibernate Query Language Interfaces utilizando critérios e exemplos

Não depende de outros módulos Não depende de uma versão específica do JDK Executável em qualquer servidor Web e/ou de

Aplicação e também em aplicações desktop

Page 26: Curso De Hibernate 3

Módulos

Hibernate Annotations Permite a escrita de metadados através de Annotations Beneficia-se da tipagem do Java Compatível com refatorações de código Semântica familiar para quem já está acostumado com

metadados em XML Utiliza as Annotations da especificação JPA Possui Annotations próprias para configurações

avançadas não presentes na especificação Necessita do JDK 5.0

Page 27: Curso De Hibernate 3

Módulos

Hibernate Entity Manager Implementação da especificação JPA Permite a escrita de código compatível com qualquer

framework de persistência que implemente a especificação

Utiliza o pacote javax.persistence Não disponibiliza todas as funcionalidades do

Hibernate

Page 28: Curso De Hibernate 3

Separação em camadas

É uma boa prática dividir aplicações de médio e grande porte em camadas Padrão Layers (Pattern-Oriented Software

architecture) Divisão mais utilizada

Apresentação Negócio Persistência

Page 29: Curso De Hibernate 3

Separação em camadas

Permite a especificação de intefaces para os diversos tipos de serviços A implementação pode ser mudada sem afetar

significativamente o código de outras camadas A comunicação ocorre das camadas superiores

para as camadas inferiores Uma camada só depende da camada

imediatamente inferior Camada de apresentação não sabe da existência da

camada de persistência

Page 30: Curso De Hibernate 3
Page 31: Curso De Hibernate 3

Criando um projeto

Page 32: Curso De Hibernate 3

Next >....

Page 33: Curso De Hibernate 3

Finish

Page 34: Curso De Hibernate 3

Adicionando as bibliotecas

Page 35: Curso De Hibernate 3

Criando uma entidade@Entity@Table(name = "MESSAGES")public class Message {

@Id@GeneratedValue@Column(name = "MESSAGE_ID")private Long id;

@Column(name = "MESSAGE_TEXT")private String text;

@ManyToOne(cascade = CascadeType.ALL)@JoinColumn(name = "NEXT_MESSAGE_ID")private Message nextMessage;

private Message() {}

public Message(String text) {this.text = text; }

//gets e sets}

Page 36: Curso De Hibernate 3

Annotations da classe

Entity Informa que a classe pode ser persistida pelo

Hibernate Table

Informa o nome da tabela em que os objetos da classe devem ser armazenados

@Entity@Table(name = "MESSAGES")public class Message {

Page 37: Curso De Hibernate 3

Construtores

Obrigatório um construtor sem argumentos

private Message() {}

public Message(String text) {

this.text = text; }

Page 38: Curso De Hibernate 3

Propriedades

Representa o identificador do objeto Preenchido automaticamente quando o objeto é

salvo Mapeado para a chave primária da tabela Se duas instâncias tiverem o mesmo

identificador, elas representam a mesma linha da tabela

@Id@GeneratedValue@Column(name =

"MESSAGE_ID")private Long id;

Page 39: Curso De Hibernate 3

Atributos

O atributo text é armazenado na coluna MESSAGE_TEXT

@Column(name = "MESSAGE_TEXT")

private String text;

O atributo nextMessage é uma associação many-to-one

Mapeado pela chave estrangeira NEXT_MESSAGE_ID

@ManyToOne(cascade = CascadeType.ALL)

@JoinColumn(name = "NEXT_MESSAGE_ID")

private Message nextMessage;

Page 40: Curso De Hibernate 3

Transparência Não há a necessidade de se herdar de uma

superclasse ou de implementar um interface POJO - Plain Ordinary Java Objects

Classes podem ser reutilizadas fora do contexto de persistência Interface com o usuário Testes de unidades

As entidades não precisam nem saber que serão persistidas

Grande nível de portabilidade

Page 41: Curso De Hibernate 3

Configurando o Hibernate Configuração feita através do arquivo

hibernate.cfg.xml Deve estar localizado na raiz do classpath

Localização default Para projetos maven, utilizar a pasta

src/main/resources Configurações contém

Parâmetros de acesso a base de dados Pool de conexões Entidades a serem persistidas

Page 42: Curso De Hibernate 3

hibernate.cfg.xml<hibernate-configuration>

<session-factory>

<!-- Parâmetros de acesso a base de dados -->

<property name="connection.driver_class">org.postgresql.Driver

</property><property name="connection.url">

jdbc:postgresql://localhost:5432/curso</property>

<property name="connection.username">postgresql</property>

<property name="connection.password">postgresql</property>

<property name="dialect">org.hibernate.dialect.PostgreSQLDialect

</property>

...

Page 43: Curso De Hibernate 3

hibernate.cfg.xml...<!-- Configuração do Pool de conexões --><property name="c3p0.min_size">5</property><property name="c3p0.max_size">20</property><property name="c3p0.timeout">300</property><property name="c3p0.max_statements">50</property><property name="c3p0.idle_test_period">3000</property>

<!-- Exibe no console o SQL gerado pelo hibernate--><property name="show_sql">true</property>

<!-- Cria e executa a DDL (tabelas, colunas, etc...)-->

<property name="hbm2ddl.auto">create</property>

<!-- Informa as Entidades da aplicação --><mappingclass="br.gov.serpro.curso.hibernate.exemplo1.Message" />

</session-factory></hibernate-configuration>

Page 44: Curso De Hibernate 3

Armazenando uma Mensagem

//Obtendo o SessionSession session = HibernateUtil.getSessionFactory().openSession();

//Iniciando a transaçãoTransaction tx = session.beginTransaction();

// Criando uma mensagemMessage message = new Message("Hello World");

// Salvando a MensagemLong msgId = (Long) session.save(message);

//Fazendo o commit da transaçãotx.commit();

//Fechando o Sessionsession.close();HibernateUtil.shutdown();

Page 45: Curso De Hibernate 3

Objetos utilizados

Session Contém métodos utilizados para armazenar e

recuperar entidades Armazena uma lista de comandos SQL que serão

executados, em algum momento, na base de dados Mantém as entidades gerenciadas pelo Hibernate

Recuperadas, inseridas ou atualizadas através do Session Único para cada thread

Page 46: Curso De Hibernate 3

Objetos utilizados

Transaction Utilizado para delimitar as transações com a base de

dados Geralmente gerenciado pelo container

EJB Spring

SessionFactory Utilizado para criar os Session Reutilizável por toda a aplicação

Page 47: Curso De Hibernate 3

HibernateUtil

public class HibernateUtil {

private static SessionFactory sessionFactory;

static {sessionFactory = new

AnnotationConfiguration().configure().buildSessionFactory();

}

public static SessionFactory getSessionFactory() {return sessionFactory;

}

public static void shutdown() {getSessionFactory().close();

}}

Page 48: Curso De Hibernate 3

Recuperando as Mensagens

Session newSession = HibernateUtil.getSessionFactory().openSession();Transaction newTransaction = newSession.beginTransaction();

//Criando e executando uma consultaQuery query = newSession

.createQuery("from Message m order by m.text asc");List<Message> messages = query.list();

//Retornando a quantidade de mensagens encontradasSystem.out.println(messages.size() + " message(s) found:");

//Retornando as mensagens encontradasfor (Message msg : messages) {

System.out.println(msg.getText());}

newTransaction.commit();newSession.close();HibernateUtil.shutdown();

Page 49: Curso De Hibernate 3

Objetos Utilizados

Query Cria as consultas Associa os parâmetros Executa as consultas

Page 50: Curso De Hibernate 3

Dirty Checking e CascadeSession thirdSession =

HibernateUtil.getSessionFactory().openSession();Transaction thirdTransaction = thirdSession.beginTransaction();

// recuperando a mensagemmessage = (Message) thirdSession.get(Message.class, msgId);

//Alterando o textomessage.setText("Greetings Earthling");

//Criando uma nova mensagem e associando à antigamessage.setNextMessage(new Message("Take me to your leader"));

thirdTransaction.commit();thirdSession.close();HibernateUtil.shutdown();

Page 51: Curso De Hibernate 3

Dirty Checking e Cascade

Dirty Checking O Hibernate automaticamente verifica quando um atributo

é modificado O atributo é atualizado na base de dados sem a necessidade

de uma chamada explicita É possível somente dentro de uma transação e para objetos

gerenciados pelo Session Cascade

Novas entidades são persistidas automaticamente Devem ser alcançáveis a partir de uma entidade gerenciada

Page 52: Curso De Hibernate 3

Metadados

Utilizados para especificar o mapeamento entre Classes e tabelas Propriedades e colunas Associações e chaves estrangeiras Tipos de atributos Java e tipos de atributos SQL

Pode ser escrita de duas formas Arquivos XML Xdoclet Java Annotations

Page 53: Curso De Hibernate 3

Porque não usar XML

Pode ser tornar pouco legível e de difícil edição Requer maior digitação Falta de valores default para atributos e elementos

Não necessariamente mais flexível e mais fácil de manter do que código Java

Mais fácil encontrar um bom editor Java do que um bom editor de XML

Page 54: Curso De Hibernate 3

Metadados com Annotations

A meta-informação fica perto dos dados que ela descreve

Compatível com refatoração de código Renomear, deletar e remover classes e propriedades

Sem necessidade de fazer parser em XML Inicialização mais rápida

Lido através de reflection na inicialização do Hibernate

Disponível a partir da JDK 5.0

Page 55: Curso De Hibernate 3

Mapeando Propriedades

Ao mapear uma classe através da Annotation @Entity, todas as propriedades serão consideradas persistentes

Propriedades não persistentes devem receber a Annotation @Transient ou o modificador transient

Por default, o nome da coluna será o mesmo da propriedade

Meio de acesso é o mesmo do @ID Definido na propriedade ou no método get()

Page 56: Curso De Hibernate 3

@Column

Aplicável para propriedades simples Atributos

name Nome da coluna a qual a propriedade é mapeada

unique Se o valor deve ser único ou não

nullable Se a propriedade pode ser nula ou não

Page 57: Curso De Hibernate 3

Mapeando Propriedades: Tipos

Page 58: Curso De Hibernate 3

Mapeando Propriedades: Tipos

Page 59: Curso De Hibernate 3

Datas

Propriedades podem ser do tipo java.util.Date ou java.util.Calendar

Precisão default é TIMESTAMP Precisão pode ser alterada através da Annotation

@Temporal

@Temporal(TemporalType.DATE)private Date date1;

@Temporal(TemporalType.TIME)private Date date2;

@Temporal(TemporalType.TIMESTAMP)private Date date3;

Page 60: Curso De Hibernate 3

Identidade das Entidades Identidade versus Equivalência em Java

Identidade Operador == Definido pela máquina virtual Dois objetos são idênticos se eles apontam para o mesmo

local da memória Equivalência

Definida pelas classes que sobreescrevem o método equals()

Dois objetos diferentes possuem o mesmo valor Dois objetos String podem ter a mesma seqüência de

caracteres

Page 61: Curso De Hibernate 3

Identidade das Entidades

Identidade na base de dados Duas Entidades são idênticas se elas representam a

mesma linha na base de dados Se são armazenadas na mesma tabela e possuem a mesma

chave primária

Page 62: Curso De Hibernate 3

Adicionando um Identificador

O valor é gerado automaticamente pelo Hibernate Não deve ser mudado pela aplicação

@Entity@Table(name="CATEGORY")public class Category {

@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "CATEGORY_ID")private Long id;

public Long getId() { return id; }}

Page 63: Curso De Hibernate 3

Escolhendo a chave primária

Uma chave candidata é uma coluna, ou um conjunto de colunas, que pode ser utilizada para identificar um registro na base de dados

Requisitos O valor nunca deve ser nulo Cada registro deve ter um valor único O valor nunca deve mudar

Page 64: Curso De Hibernate 3

Escolhendo a chave primária

Chaves naturais são aquelas que possuem significado para o domínio da aplicação CPF de um usuário Seqüencial gerado pela aplicação

Dificilmente chaves naturais atendem os requisitos necessários

Page 65: Curso De Hibernate 3

Escolhendo a chave primária

Chaves cegas Melhor alternativa Não possuem significado para o domínio da aplicação Geradas pelo banco de dados ou pela aplicação

Page 66: Curso De Hibernate 3

Geração automática de chaves

Hibernate suporta diversas estratégias para geração automática de chaves

A estratégia deve ser especificada através da Annotations @GeneratedValue

Page 67: Curso De Hibernate 3

Estratégias

IDENTITY Suporte para colunas IDENTITY nos bancos de dados

DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL

Os tipos devem ser long, short ou int SEQUENCE

Utiliza um Sequence para a geração de chaves Suporte para DB2, PostgreSQL e Oracle dentre outros Nome default da sequence é hibernate_sequence

Page 68: Curso De Hibernate 3

Estratégias

increment Na inicialização o Hibernate lê qual o maior valor

para a chave da tabela O valor é atribuído e incrementado em cada inserção Não deve ser utilizado se o Hibernate não tiver acesso

exclusivo para a base de dados

Page 69: Curso De Hibernate 3

Estratégias

AUTO Escolhe entre as estratégias IDENTITY, SEQUENCE

ou HILO Estratégia escolhida depende do banco de dados

utilizado Utilizado para manter a portabilidade

Outras hilo, seqhilo, uuid.hex, guid, select IdentifierGenerator

Permite a implementação de sua própria estratégia

Page 70: Curso De Hibernate 3

Mapeando Componentes

Entidades são classes persistentes que representam objetos do domínio da aplicação Possuem identidade própria

Hibernate suporta a construção de um modelo de objetos de alta granularidade Propriedades de uma Entidade podem ser

encapsuladas em outros objetos Tais objetos não possuem identidade própria Chamados de Objetos Valores ou Componentes

Mais classes do que tabelas

Page 71: Curso De Hibernate 3

Mapeando Componentes

Page 72: Curso De Hibernate 3

Mapeando Componentes

User Representa uma Entidade Possui identidade própria

Chave primária na base de dados Uma referência para User é persistida como uma

chave estrangeira Tem seu próprio ciclo de vida

Existe independentemente de qualquer outra entidade

Page 73: Curso De Hibernate 3

Mapeando Componentes

Address Representa um Componente Não possui identidade própria Pertence a Entidade User Estado é persistido no registro referente ao User a

qual está associado Ciclo de vida dependente de User Se dois Usuários morarem no mesmo apartamento,

cada um tem uma referência para um objeto distinto Comportamento similar a tipos como String e Integer

Page 74: Curso De Hibernate 3

Mapeando Componentes

@Embeddablepublic class Address {

@Column(name = "ADDRESS_STREET", nullable = false)private String street;

@Column(name = "ADDRESS_CITY", nullable = false)private String city;

//gets e sets...}

Page 75: Curso De Hibernate 3

Mapeando Componentes

@Entity@Table(name = "USERS")public class User {

@Id@GeneratedValue(strategy=GenerationType.AUTO)private Long id;

private String name;

private String email;

private Address address;

//gets e sets}

Page 76: Curso De Hibernate 3

Mapeando Herança

A utilização de uma tabela para cada entidade não funciona tão bem para heranças entre entidades

Bancos de dados SQL, de maneira geral, não possuem o conceito de herança Soluções proprietária podem comprometer a

portabilidade da aplicação

Page 77: Curso De Hibernate 3

Estratégias

Tabela por classe concreta Tabela por classe concreta, utilizando junção Tabela por hierarquia Tabela por classe (concreta ou não)

Page 78: Curso De Hibernate 3

Uma tabela por Classe Concreta: Modelagem

Page 79: Curso De Hibernate 3

Uma tabela por Classe Concreta

Estratégia mais simples Todas propriedades de uma classe, incluindo as

herdadas, são mapeadas para a mesma tabela Mapeamento convencional pode ser utilizado Não suporta associações polimórficas

adequadamente Associação para classe abstrata necessitaria que a

chave estrangeira referenciasse duas tabelas

Page 80: Curso De Hibernate 3

Uma tabela por Classe Concreta

Diferentes colunas em diferentes tabelas passariam a possuir a mesma semântica

Recomendável somente para a hierarquia superior Associações polimórficas geralmente não necessárias

e não recomendadas Modificações na superclasse são muito raras

select CREDIT_CARD_ID, OWNER, NUMBER, EXP_MONTH, EXP_YEAR ...from CREDIT_CARD

select BANK_ACCOUNT_ID, OWNER, ACCOUNT, BANKNAME, ...from BANK_ACCOUNT

Page 81: Curso De Hibernate 3

Mapeando a Superclasse

@MappedSuperclasspublic abstract class BillingDetails {

@Column(name = "OWNER", nullable = false)private String owner;

//gets e sets...}

Mapear a super classe através da Annotattion @MappedSuperclass

Page 82: Curso De Hibernate 3

Mapeando as Subclasses

Nenhuma configuração extra é necessária

@Entitypublic class BankAccount extends BillingDetails{

@Id@GeneratedValueprivate Long id;

private Integer account;

private String bank;}

Page 83: Curso De Hibernate 3

Mapeando as Subclasses

Mapeamento das propriedades herdadas pode ser alterado

Adicionar a Annotation @AttributeOverride

@Entity@AttributeOverride(name = "owner", column = @Column(name =

"CC_OWNER", nullable = false))public class CreditCard extends BillingDetails {

@Id@GeneratedValueprivate Long id;

private String number; }

Page 84: Curso De Hibernate 3

Uma tabela por Classe Concreta: Union

Com a utilização de consultas com Union, alguns problemas podem ser eliminados

Suporte a associações polimórficas Hibernate utiliza o Union para simular uma única

tabela As subclasses herdam o Id da super-classe

Page 85: Curso De Hibernate 3

Mapeando a Super Classe

@Entity@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)public class BillingDetails {

@Id @GeneratedValue@Column(name = "BILLING_DETAILS_ID")private Long id = null;

@Column(name = "OWNER", nullable = false)private String owner;

}

É utilizada a Annotation @Inheritance

Page 86: Curso De Hibernate 3

Mapeando as Subclasses

@Entitypublic class CreditCard extends BillingDetails{

@Column(name = "CC_NUMBER")private String number;

}

Não é necessário mapear o identificador O Identificador é mapeado na super-classe

Page 87: Curso De Hibernate 3

Tabela por Hierarquia

Page 88: Curso De Hibernate 3

Tabela por Hierarquia

Toda uma hierarquia é mapeada em uma única tabela

A tabela possui colunas para todas as propriedades de todas as entidades da hierarquia

A subclasse de cada registro é identificada através de uma coluna discriminatória

Vantagem Possui a melhor performance

Page 89: Curso De Hibernate 3

Tabela por Hierarquia

Desvantagens Valores para colunas das subclasses devem sempre

permitir NULL Perca da restrição NOT NULL

Dados são desnormalizados

Page 90: Curso De Hibernate 3

Mapeando a Superclasse

@Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)public abstract class BillingDetails {

@Id @GeneratedValue@Column(name = "BILLING_DETAILS_ID")private Long id = null;

@Column(name = "OWNER", nullable = false)private String owner;

}

O valor do atributo strategy deve ser mudado para InheritanceType.SINGLE_TABLE

Page 91: Curso De Hibernate 3

Tabela por classe

Page 92: Curso De Hibernate 3

Tabela por classe

Uma tabela para todas as classes, incluindo as abstratas, que possuem propriedades para serem persistidas

Relação de herança é representada por uma chave estrangeira

As tabelas não contém colunas para as propriedades herdadas

A chave primária é também uma chave estrangeira para a super classe

Page 93: Curso De Hibernate 3

Tabela por classe

Vantagens Os dados são normalizados Restrições podem ser mantidas

Desvantagens Performance pode ser muito baixa para hierarquias

complexas Necessidade de muitas junções

Page 94: Curso De Hibernate 3

Mapeando a Superclasse

@Entity@Inheritance(strategy = InheritanceType.JOINED)public abstract class BillingDetails {

@Id @GeneratedValue@Column(name = "BILLING_DETAILS_ID")private Long id = null;

@Column(name = "OWNER", nullable = false)private String owner;

}

O valor do atributo strategy deve ser mudado para InheritanceType.JOINED

Page 95: Curso De Hibernate 3

Mapeando as Subclasses

@Entitypublic class CreditCard extends BillingDetails{

@Column(name = "CC_NUMBER")private String number;

}

Id é mapeado na super-classe

Page 96: Curso De Hibernate 3

Escolhendo a melhor estratégia

Tabela por classe concreta, utilizando junção Se associações ou consultas polimórficas nunca ou

raramente são utilizadas Tabela por hierarquia

Se associações ou consultas polimórficas são utilizadas e

Se as subclasses declaram poucas propriedades Maior diferença entre as subclasses é o comportamento

Page 97: Curso De Hibernate 3

Escolhendo a Melhor Estratégia

Tabela por Classe Se associações ou consultas polimórficas são

utilizadas e Se as subclasses declaram muitas propriedades

Maior diferença entre as subclasses são os dados que elas armazenam

Se a largura e o comprimento da hierarquia não for muito grande

Page 98: Curso De Hibernate 3

Mapeando coleções

Objetos podem possuir coleções As coleções podem ter duas naturezas

Coleções de valores Tipos primitivos Componentes

Coleções de entidades

Page 99: Curso De Hibernate 3

Coleção de tipos primitivos: Set

Um Item possui um conjunto de imagens Somente o nome da imagem é persistido Nomes não devem ser duplicados para um

determinado Item

Page 100: Curso De Hibernate 3

Annotations

@CollectionOfElements Utilizada para coleções de tipos primitivos ou para

coleções de objetos valores @JoinTable

Informa a tabela em que a coleção é persistida Atributos

Name Nome da tabela

JoinColumns Coluna que é chave estrangeira Chave estrangeira referencia a tabela da entidade que possui a coleção

Page 101: Curso De Hibernate 3

Annotations

@JoinColumn É o tipo do atributo JoinColumns da Annotation

@JoinTable Annotation dentro de outra Annotation

Mapeia a coluna utilizada para junções Atributos

Name Nome da coluna

Page 102: Curso De Hibernate 3

Classe Item

@Entitypublic class Item {

@Id @GeneratedValue@Column(name = "ITEM_ID")private Long id;

private String name;

@CollectionOfElements@JoinTable(name = "ITEM_IMAGE", joinColumns = @JoinColumn(name

= "ITEM_ID"))@Column(name = "FILENAME", nullable = false)private Set<String> images = new HashSet<String>();

}

Page 103: Curso De Hibernate 3

Coleção de tipos primitivos: List

Caso a aplicação necessite guardar a ordem dos elementos

Necessário uma coluna para informar a posição de cada elemento

Page 104: Curso De Hibernate 3

Classe Item

@Entitypublic class Item {...

@CollectionOfElements@JoinTable(name = "ITEM_IMAGE", joinColumns = @JoinColumn(name = "ITEM_ID"))@Column(name = "FILENAME", nullable = false)@IndexColumn(name = "POSITION")private List<String> images = new ArrayList<String>();

}

Deve-se adicionar a Annotation @IndexColumn

Page 105: Curso De Hibernate 3

Coleção de tipos primitivos: Map

Se o Item possuir um Map de imagens É necessário guardar o elemento e sua chave

Page 106: Curso De Hibernate 3

Classe Item

@Entitypublic class Item {...

@CollectionOfElements@JoinTable(name = "ITEM_IMAGE", joinColumns =

@JoinColumn(name = "ITEM_ID"))@Column(name = "FILENAME", nullable = false)@MapKey(columns = @Column(name = "IMAGENAME"))private Map<String, String> images = new HashMap<String,

String>();}

Utilizar a Annotation @MapKey Atributo columns informa o nome da coluna que

armazena a chave

Page 107: Curso De Hibernate 3

Associação entre Entidades

Podem ser de diversas multiplicidades One-to-many One-to-one Many-to-many Many-to-one

Também são implementadas através de atributos Para associações one-to-many e many-to-many é

necessário a utilização de coleções

Page 108: Curso De Hibernate 3

Implementando associações

Coleções devem ser acessadas através de suas Interfaces Set, ao invés de HashSet List, ao invés de ArrayList

Page 109: Curso De Hibernate 3

Associações Bidirecionais

Os dois lados da associação devem estar consistentes Necessário mesmo para aplicações que não usam

Hibernate

Page 110: Curso De Hibernate 3

Classe Category

public class Category {

private String name;

private Category parentCategory;

private Set<Category> childCategories = new HashSet<Category>();

//gets e sets//...

}

Page 111: Curso De Hibernate 3

Mantendo a Consistência

Category aParent = new Category();Category aChild = new Category();

aChild.setParentCategory(aParent);aParent.getChildCategories().add(aChild);

Page 112: Curso De Hibernate 3

Relacionamento Pai-Filho

Page 113: Curso De Hibernate 3

Classe Bid

Relaciona-se a somente um Item Mapeamento realizado através da Annotation

@ManyToOne Annotation @JoinColumn informa qual a chave

estrangeira Atributo name

Nome da coluna Atributo nullable

Se o relacionamento é opcional ou não

Page 114: Curso De Hibernate 3

Classe Bid

@Entitypublic class Bid {

@Id@GeneratedValue@Column(name = "BID_ID")private Long id;

private Integer amount;

@ManyToOne@JoinColumn(name = "ITEM_ID", nullable = false)private Item item;

}

Page 115: Curso De Hibernate 3

Relacionamento Bidirecional

O relacionamento pode ou não ser declarado como bidirecional

Para relacionamentos bidirecionais o outro lado da associação é mapeado com a Annotation inversa @OneToMany no caso de Item

Classe Bid utiliza a Annotation @ManyToOne

Page 116: Curso De Hibernate 3

Relacionamento Bidirecional

@Entitypublic class Item {

@Id@GeneratedValue@Column(name = "ITEM_ID")private Long id;

private String name;

@OneToMany(mappedBy = "item")private Set<Bid> bids = new HashSet<Bid>();

}

Page 117: Curso De Hibernate 3

Relacionamento Bidirecional

@OneToMany(mappedBy = "item") Detalhes do mapeamento são configurados no outro lado

da associação Através da Annotation @ManyToOne

Quando as referências de uma associação mudam, as duas propriedades são alteradas bid.setItem(item); item.getBids().add(bid);

Page 118: Curso De Hibernate 3

Relacionamento Bidirecional

Na base de dados somente uma atualização precisa ser feita Atualização da chave estrangeira Hibernate não precisa executar dois comandos

UPDATE Uma das alterações é sincronizada e a outra é

ignorada Não há efeito colateral se as associações estiverem

consistentes

Page 119: Curso De Hibernate 3

Relacionamento Bidirecional

O lado que contém os detalhes do mapeamento é o lado que é sincronizado Relacionamentos many-to-one ou one-to-many

Lado Many é sincronizado Relacionamento one-to-one

Lado que possuir a chave estrangeira é sincronizado Relacionamento many-to-many

Lado que mapear a tabela de junção é sincronizado Os lados do relacionamento não sincronizados

possuem o atributo mappedBy na Annotation

Page 120: Curso De Hibernate 3

Relacionamento Bidirecional

Bid bid = new Bid();bid.setAmount(Integer.valueOf(1000));

Item item = new Item();item.setName("computador");

bid.setItem(item);item.getBids().add(bid);

Session session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

//O item tem que ser salvo primeirosession.save(item);session.save(bid);

Page 121: Curso De Hibernate 3

Relacionamento One-to-One

Page 122: Curso De Hibernate 3

One-to-One

O atributo deve conter a Annotation @OneToOne Se o relacionamento for bidirecional os dois

atributos devem conter a Annotation Em uma das propriedades deve ser adicionada a

Annotation @JoinColumn Na outra propriedade deve ser adicionado o

atributo mappedBy à Annotation @OneToOne

Page 123: Curso De Hibernate 3

Classe User

@Entity@Table(name = "USERS")public class User {

@Id@GeneratedValue(strategy=GenerationType.AUTO)private Long id;

private String name;

@OneToOne@JoinColumn(name = "SHIPPING_ADDRESS_ID")private Address address;

}

Page 124: Curso De Hibernate 3

Classe Address

@Entitypublic class Address {

@Id@GeneratedValueprivate Long id;

@Column(nullable = false)private String street;

@OneToOne(mappedBy = "address")private User user;

}

Page 125: Curso De Hibernate 3

Ralacionamento Many-to-Many

Page 126: Curso De Hibernate 3

Many-to-Many

O atributo deve conter a Annotation @ManyToMany

Se o relacionamento for bidirecional os dois atributos devem conter a Annotation

Em uma das propriedades deve ser adicionada a Annotation @JoinTable

Na outra propriedade deve ser adicionado o atributo mappedBy à Annotation @ManyToMany

Page 127: Curso De Hibernate 3

@JoinTable

Contém o nome da tabela de relacionamento O atributo joinColumns mapeia a coluna

associada à entidade mapeada O tipo do atributo é @JoinColumn

Annotation dentro de annotation O atributo inverseJoinColumns mapeia a coluna

associada à outra entidade O tipo do atributo também é @JoinColumn

Page 128: Curso De Hibernate 3

Classe Category

@Entitypublic class Category {

@Id@GeneratedValue@Column(name = "CATEGORY_ID")private Long id;

private String name;

@ManyToMany@JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name

= "CATEGORY_ID"), inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))private Set<Item> items = new HashSet<Item>();

}

Page 129: Curso De Hibernate 3

Classe Item

@Entitypublic class Item {

@Id@GeneratedValue@Column(name = "ITEM_ID")private Long id;

private String name;

@ManyToMany(mappedBy = "items")private Set<Category> categories = new

HashSet<Category>();}

Page 130: Curso De Hibernate 3

Polimorfismo e LazyLoading

Utilizando-se polimorfismo, as entidades são referenciadas através de suas super classes

Não se deve fazer o cast da referência para alguma das subclasses, mesmo que se saiba o tipo do objeto

Para associações carregadas por LazyLoading, é utilizado um objeto proxy

O objeto proxy não pode ser atribuído a uma subclasse da classe referenciada

Page 131: Curso De Hibernate 3

Associações: Polimorfismo

Page 132: Curso De Hibernate 3

Entidade User

@Entity@Table(name = "USERS")public class User {

@Id@GeneratedValueprivate Long id;

@OneToOne(fetch = FetchType.LAZY)@JoinColumn(name = "DEFAULT_BILLING_ID")private BillingDetails defaultBilling; }

Page 133: Curso De Hibernate 3

Polimorfismo e LazyLoading

User user = (User) session.get(User.class, userId);BillingDetails bd = user.getDefaultBilling();

CreditCard cc = (CreditCard) session.load(CreditCard.class, bd.getId());System.out.println(cc.getNumber());

User user = (User) session.get(User.class, userId);BillingDetails billingDetails = user.getDefaultBilling();

//imprime falseSystem.out.println(billingDetails instanceof CreditCard);

//ClassCastExceptionCreditCard creditCard = (CreditCard) billingDetails;

Page 134: Curso De Hibernate 3

Ciclo de Vida dos Objetos

Em seu ciclo de vida, uma entidade pode assumir diversos estados relativos a sua persistência Transiente Persistente Desconectada Removida

Entidades devem se comportar de maneira apropriada mesmo que ainda não estejam persistentes

Page 135: Curso De Hibernate 3

Ciclo de Vida dos Objetos

O ciclo de vida de uma entidade pode ser afetado através de chamadas às interfaces do Hibernate Operações de alterações e consultas na base de dados Operações para delimitar a existência de uma

transação e de um Sesssion Para o correta implementação, a aplicação deve

se preocupar com o estado e o ciclo de vida do objeto

Page 136: Curso De Hibernate 3

Ciclo de Vida dos Objetos: Conceitos Unidade de trabalho

Conjunto de operações, geralmente atômicas Contexto de persistência

Cache de todas alterações feitas em entidades em uma única unidade de trabalho

Page 137: Curso De Hibernate 3

Estado Transiente

É o estado que um objeto assume quando é criado através do operador new

Não está associado a nenhum registro da base de dados

Os dados são perdidos quando o objeto não é mais referenciado e torna-se disponível para o Coletor de Lixo

Não são gerenciados pelo Hibernate Não possuem comportamento transacional

Page 138: Curso De Hibernate 3

Estado Persistente

É uma entidade com um identificador na base de dados Possui uma chave primária

São objetos gerenciados pelo Hibernate Podem ser objetos criados pela aplicação

Tornam-se persistentes através de chamadas ao Hibernate

Tornam-se persistentes se passarem a ser referenciados por outros objetos persistentes

Depende do tipo de Cascade

Page 139: Curso De Hibernate 3

Persistente

Podem ser objetos retornados da base de dados Através de uma consulta Através de uma associação entre um objeto persistente

Podem ser objetos atualizados na base de dados São sempre associados a um Contexto de

Persistência São guardados em um cache Hibernate identifica qualquer alteração realizado no

objeto

Page 140: Curso De Hibernate 3

Removido

Um objeto pode ser removido de duas maneiras Uma chamada explicita ao Hibernate Através de uma operação com Cascade

Um objeto neste estado é removido ao final da Unidade de Trabalho É gerenciado pelo Contexto de Persistência até que a

Unidade de Trabalho termine

Page 141: Curso De Hibernate 3

Desconectado

Objetos Persistentes passam para o estado Desconectado quando a Unidade de Trabalho é completada e o Contexto de Persistência é encerrado

O objeto não é mais sincronizado com a base de dados

Os dados do objeto podem se tornar desatualizados Seus dados ainda podem ser alterados pela aplicação Podem voltar ao estado Persistente

Page 142: Curso De Hibernate 3

Contexto de Persistência

Mantém um cache de instâncias gerenciadas Entidades no estado Persistente e Removido

Conceito abstrato Não representado por um único objeto

Cada objeto Session possui um Contexto de Persistência

Permite Dirty Checking automático Delimita um escopo para a identidade das Entidades

Não possui instâncias duplicadas

Page 143: Curso De Hibernate 3

Dirty Checking Automático É possível através do Contexto de Persistência O dados de uma entidade são sincronizados com

a base de dados No final da unidade de trabalho Em outros momentos: antes de uma consulta

Somente os objetos alterados são atualizados na base de dados

Atualização é retardada o máximo possível e é feita de forma automática Tempo de Lock do banco de dados é reduzido

Page 144: Curso De Hibernate 3

Cache de Primeiro Nível

Armazenado no Contexto de Persistência Mantém todas as instâncias de uma Unidade de

Trabalho Provê ganho de performance para a aplicação Torna possível Repeatable Read

Ao buscar mais de uma vez uma mesma entidade, os dados retornados são os mesmos

O escopo é restrito à thread de execução

Page 145: Curso De Hibernate 3

Cache de Primeiro Nível

Um único objeto representa um determinado registro na base de dados Evita alterações conflitantes

Page 146: Curso De Hibernate 3

Contexto Persistência: Escopo

Algumas funcionalidades da aplicação necessitam de diversas requisições para serem completadas

O escopo do Contexto de Persistência pode, ou não, ser o mesmo da funcionalidade

Duas estratégias são as mais utilizadas para delimitar o escopo do Contexto de Persistência Um objeto Session por requisição Unidade de Trabalho de longa duração

Page 147: Curso De Hibernate 3

Uma Session por Requisição

Quando o servidor recebe alguma requisição que requer acesso a base de dados uma nova Unidade de Trabalho é iniciada

A Unidade de Trabalho é encerrada quando a requisição é processada e a resposta está pronta para ser enviada ao usuário

As entidades são mantidas em estado Desconectado entre uma requisição e outra

Page 148: Curso De Hibernate 3

Uma Session por Requisição

Entidades mantidas entre duas requisições necessitam ser reconectadas para acessar serviços de persistência novamente

Qualquer alteração feita em entidades desconectadas deve ser sincronizada manualmente Operações de atualização e/ou merge

Page 149: Curso De Hibernate 3

Objetos Desconectados

Page 150: Curso De Hibernate 3

Unidade de Trabalho de Longa Duração

Objeto Session é mantido aberto durante várias requisições O Contexto de Persistência se propaga durante toda a

conversação Conexões com a base de dados não são mantidas

abertas A cada nova requisição o contexto é reconectado à base

de dados As entidades são mantidas no estado Persistente

Não requer merge ou atualização manual

Page 151: Curso De Hibernate 3

Unidade de Trabalho de Longa Duração

No final da conversação, o Contexto é sincronizado com a base de dados e encerrado

A atomicidade das alterações é relativa à funcionalidade como um todo

Page 152: Curso De Hibernate 3

Contexto expandido

Page 153: Curso De Hibernate 3

Escopo limitado ao Contexto de Persistência

Session session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

Long id = (Long) session.save(new Message("Hibernate"));

Message messageB = (Message) session.get(Message.class, id);Message messageC = (Message) session.get(Message.class, id);

System.out.println(messageB.equals(messageC));

transaction.commit();session.close();

Session session2 = HibernateUtil.getSessionFactory().openSession();Transaction transaction2 = session2.beginTransaction();

Message messageD = (Message) session2.get(Message.class, id);System.out.println(messageC.equals(messageD));

Page 154: Curso De Hibernate 3

Identidade de objetos Desconectados

Sempre que se for trabalhar com objetos desconectados, deve-se sobrescrever o método equals() Para objetos desconectados a garantia de uma única

instância por registro é perdida Implementação default não garante o comportamento

desejado Mesmo que dois objetos possuam todas as

propriedades iguais, o método pode retornar false

Page 155: Curso De Hibernate 3

equals() Deve retornar verdadeiro se duas instâncias

corresponderem ao mesmo registro Quais propriedades devem ser comparadas? Somente a chave primária

Problema: entidades transientes não possuem valores para a chave primária

Todas as propriedades Problema: entidades referentes ao mesmo registro não

são consideradas iguais se alguma propriedade mudar Melhor abordagem: comparar a chave de negócio

Page 156: Curso De Hibernate 3

Chave de negócio

Uma propriedade, ou um conjunto delas, que é único para cada registro Chave candidata

Não precisa ser imutável, basta que mude com pouca freqüência

Page 157: Curso De Hibernate 3

Implementaçãopublic boolean equals(Object other) {

if (!(other instanceof User)){return false;

}User that = (User) other;return this.name.equals(that.getName());

}

public int hashCode() {return this.name.hashCode();

}

Page 158: Curso De Hibernate 3

Interagindo com o Hibernate

O Hibernate provê diversos serviços Operações CRUD

Criar Recuperar Atualizar Deletar

Realização de consultas Controle de transação Gerenciamento do Contexto de Persistência

Page 159: Curso De Hibernate 3

Interagindo com o Hibernate

Os serviços são disponibilizados através de diversas Interfaces Session Transaction Query Criteria

Page 160: Curso De Hibernate 3

Armazenando e Recuperando Objetos

Para armazenar ou recuperar objetos, é necessário iniciar uma Unidade de Trabalho

Session session = sessionFactory.openSession();Transaction transaction = session.beginTransaction();

Um Contexto de Persistência é criado Irá gerenciar todas as entidades do Session

Uma transação também deve ser iniciada mesmo para operações de leitura

Page 161: Curso De Hibernate 3

Armazenando um Objeto

// Quando é instanciado, o item está no estado TransienteItem item = new Item();item.setName("Item 1");

// um novo Session é abertoSession session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

// O item passa para o estado Persistente e fica associado//ao Session e ao Contexto de Persistênciasession.save(item);

//As mundanças são sincronizadas com a base de dadostransaction.commit();

//O Session é fechado e o Contexto de Persistência encerrado.//O item passa para o estado Desconectadosession.close();

Page 162: Curso De Hibernate 3

Armazenando um Objeto

Page 163: Curso De Hibernate 3

Recuperando uma Entidade

Session session = HibernateUtil.getSessionFactory().openSession();Transaction tx = session.beginTransaction();

//Item é recuperado no estado TransienteItem item = (Item) session.load(Item.class, new Long(1234));// Item item = (Item) session.get(Item.class, new Long(1234));

tx.commit();

//Item passa para o estado Desconectadosession.close();

Page 164: Curso De Hibernate 3

Recuperando uma Entidade

Page 165: Curso De Hibernate 3

Recuperando uma Entidade

Método get() Se o objeto procurado não for encontrado, retorna null

Método load() Se o objeto procurado não for encontrado, lança a

exceção ObjectNotFoundException A existência do objeto só é verificada quando alguma

propriedade é acessada

Page 166: Curso De Hibernate 3

Modificando um Objeto Persistente

Todo objeto retornado pelos métodos load() ou get() ou através de uma consulta, assume o estado Persistente

Os objetos podem ser modificados e as alterações são sincronizadas com a base de dados

Page 167: Curso De Hibernate 3

Modificando um Objeto Persistente

Long id = armazenarItem();

Session session = HibernateUtil.getSessionFactory().openSession();Transaction tx = session.beginTransaction();

Item item = (Item) session.get(Item.class, id);item.setName("Playstation");

//Dados sincronizados com a base de dados. Dirty Cheking automáticotx.commit();session.close();

Page 168: Curso De Hibernate 3

Modificando um Objeto Persistente

Page 169: Curso De Hibernate 3

De Persistente para Transiente

Long id = armazenarItem();

Session session = HibernateUtil.getSessionFactory().openSession();Transaction tx = session.beginTransaction();

//Item no estado PersistenteItem item = (Item) session.load(Item.class, id);

//Item no estado Removidosession.delete(item);

tx.commit();

//Item no estado Transientesession.close();

Page 170: Curso De Hibernate 3

De Persistente para Transiente

Page 171: Curso De Hibernate 3

Trabalhando com Objetos Desconectados

Modificações realizadas em objetos Desconectados não são sincronizadas na base de dados

A atualização da base de dados pode ser feita de duas formas Reconectando o objeto – reattach Realizando o merge do objeto

Page 172: Curso De Hibernate 3

Reconectando um Objeto

Um objeto é reconectado através do método update() da interface Session

O objeto passa a ser gerenciado pelo Session e assume o estado Persistente

Deve-se ter certeza de que o Session ainda não possui um objeto gerenciado com o mesmo Id Somente uma instância do Contexto de Persistência

pode estar associada a um determinado registro

Page 173: Curso De Hibernate 3

Reconectando um Objeto

Item item = recuperarItem(armazenarItem());

item.setName("Novo nome");

Session session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

session.update(item);

item.setPrice(Integer.valueOf(114));

transaction.commit();session.close();

Page 174: Curso De Hibernate 3

Reconectando um Objeto

Page 175: Curso De Hibernate 3

NonUniqueObjectException

Long id = armazenarItem();Item item = recuperarItem(id);

item.setName("Novo nome");

Session session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

Item item2 = (Item) session.get(Item.class, id);session.update(item);

item.setPrice(Integer.valueOf(114));

transaction.commit();session.close();

Page 176: Curso De Hibernate 3

Realizando o merge() de um Objeto

O merge de um objeto é feito através do método merge() da Interface Session

A a base de dados é atualizada com os valores contidos no objeto

Os dados do objeto também atualizam o objeto persistente que possuir o mesmo identificador Se não existir um objeto persistente associado ao

Session, ele é carregado

Page 177: Curso De Hibernate 3

Método merge()

O objeto desconectado não passa a ser associado ao Session Continua desconectado

O objeto persistente é retornado

Page 178: Curso De Hibernate 3

Método merge()

Long id = armazenarItem();Item item = recuperarItem(id);

item.setName("Novo nome!!!");

Session session = HibernateUtil.getSessionFactory().openSession();Transaction transaction = session.beginTransaction();

Item item2 = (Item) session.get(Item.class, id);Item item3 = (Item) session.merge(item);

transaction.commit();session.close();

Page 179: Curso De Hibernate 3

Método merge()

Page 180: Curso De Hibernate 3

Persistência Transitiva

Em aplicações não triviais, diversas Entidades podem estar associadas

A aplicação deve poder manipular as associações Uma rede de objetos pode consistir de objetos em

diferentes estados Persistentes Desconectados Transientes

Page 181: Curso De Hibernate 3

Persistência Transitiva A Persistência Transitiva permite persistir objetos

Desconectados e Transientes automaticamente Um objeto Transiente associado a um Persistente,

torna-se persistente automaticamente Não há necessidade de chamar o método save()

Diversas operações poder ser cascateadas Salvar Deletar Reconectar (update) Merge

Page 182: Curso De Hibernate 3

Cascade

Por default, em nenhuma operação é feito o cascade O Hibernate permite a configuração do tipo de

comportamento desejado para cada associação Todos os tipos de associações podem ser

configuradas one-to-one one-many many-to-many many-to-one

Page 183: Curso De Hibernate 3

org.hibernate.annotations.CascadeType

SAVE_UPDATE Objetos transientes são salvos Objetos desconectados são sincronizados

DELETE Objetos relacionados são deletados após a chamada

do método delete() ALL

Habilita todos os tipos de cascade

Page 184: Curso De Hibernate 3

org.hibernate.annotations.CascadeType

DELETE_ORPHAN Deleta um objeto se ele for excluído da coleção Aplicável somente para relacionamentos One-to-

Many Cascade é aplicável somente para

relacionamentos entre entidades

Page 185: Curso De Hibernate 3

Exercício

Page 186: Curso De Hibernate 3

Consultas

Umas das partes mais interessantes do acesso a dados Consultas complexas podem levar um bom tempo

para serem escritas e podem ter considerável impacto na performance da aplicação

Consultas são escritas utilizando conceitos de orientação a objetos Objetos no lugar de tabelas Propriedades no lugar de colunas

Experiência em SQL não é desprezada

Page 187: Curso De Hibernate 3

Consultas

Podem ser feitas de três maneiras Hibernate Query Language (HQL) Criteria API e Query by Example Utilizando SQL

Page 188: Curso De Hibernate 3

Consultas: Exemplos

// Através de HQLsession.createQuery("from Category c where c.name like 'Laptop%'");

// Utilizando-se Criteriasession.createCriteria(Category.class).add(

Restrictions.like("name", "Laptop%"));

// Através de SQLsession.createSQLQuery(

"select {c.*} from CATEGORY {c} where NAME like 'Laptop%'").addEntity("c", Category.class);

Page 189: Curso De Hibernate 3

Consultas

Envolve alguns passos Criar a consulta com as restrições necessárias Adicionar parâmetros à consulta Executar a consulta e recuperar o resultado

A forma de execução da consulta e obtenção dos dados pode ser configurada

Page 190: Curso De Hibernate 3

Criando a Consulta

Query query = session.createQuery("from User");

Criteria criteria = session.createCriteria(User.class);

Objetos Query e Criteria são obtidos através do Session org.hibernate.Query org.hibernate.Criteria

Page 191: Curso De Hibernate 3

Adicionando Parâmetros à Consulta

Parâmetros não devem ser adicionados na própria String da consulta "from Item i where i.description like '" + search + "'"

Evita-se ataque do tipo SQL Injection foo' and callSomeStoredProcedure() and 'bar' = 'bar

Parâmetros podem ser adicionados através de sua posição ou de seu nome

Page 192: Curso De Hibernate 3

Adicionando Parâmetros pelo Nome

String queryString = "from Item item where item.description like :search";

Query q = session.createQuery(queryString).setString("search",searchString);

String queryString = "from Item item"+ " where item.description like :search"+ " and item.date > :minDate";

Query q = session.createQuery(queryString).setString("search",searchString).setDate("minDate", mDate);

Nome do parâmetro é precedido de “:” O valores são adicionados através de métodos

sets

Page 193: Curso De Hibernate 3

Adicionando Parâmetros pela Posição

String queryString = "from Item item"+ " where item.description like ?" + " and item.date > ?";

Query q = session.createQuery(queryString).setString(0, searchString).setDate(1, minDate);

A consulta contém “?” para indicar a existência de alguma parâmetro

Os valores também são adicionado através de métodos sets

Page 194: Curso De Hibernate 3

Executando a Consulta

Se mais de um objeto pode ser retornado, chama-se o método list() List list = query.list();

Se somente um objeto pode ser retornado, chama-se o método uniqueResult() User user = (User) query.uniqueResult(); O método retorna null se nenhum objeto for

encontrado Se a consulta retornar mais de um objetos, a exceção

NonUniqueResultException é lançada

Page 195: Curso De Hibernate 3

Executando a Consulta

Query query = session.createQuery("from User");List<User> list = query.list();

for (User user : list) {System.out.println(user.getName());

}

Query query2 = session.createQuery("from User user where user.name =:name").setString("name","SUNSP");

User user = (User) query2.uniqueResult();

System.out.println(user.getName());

Page 196: Curso De Hibernate 3

Consultas Básicas A consulta mais simples tem somente a cláusula

FROM “from Item”

Para se referenciar as propriedades de uma entidade, um ALIAS deve ser criado “from Item as item” “from Item item”

Palavra chave “as” é opcional A consulta não é case-sensitive

“FROM Item AS item” também pode ser utilizada

Page 197: Curso De Hibernate 3

Consultas Polimórficas

Consultas podem ser escritas utilizando polimorfismo

“from BillingDetails” Retorna todas as entidades que herdam de

BillingDetails CreditCard BankAccount

A superclasse não precisa estar mapeada “from java.lang.Object” “from java.io.Serializable”

Page 198: Curso De Hibernate 3

Restrições

Geralmente não se quer trazer todo o conteúdo da tabela

Restrições devem ser adicionadas para restringir os objetos retornados

HQL também utiliza-se a cláusula WHERE As restrições são feitas sobre propriedades da

entidade

Page 199: Curso De Hibernate 3

Restrições

Literais e condições podem ser incluídos Utiliza-se aspas simples para literais do tipo String “from User u where u.email = '[email protected]'” “from Item i where i.isActive = true”

Comparações podem ser realizadas “from Bid bid where bid.amount between 1 and 10” “from Bid bid where bid.amount > 100” “from User u where u.email in ('foo@bar', 'bar@foo')”

Page 200: Curso De Hibernate 3

Operador LIKE pode ser utilizado “%” representa qualquer seqüência de caracteres _ (Under_Score) representa qualquer caractere “from User u where u.firstname like 'G%'” Negação pode ser utilizada

“from User u where u.firstname not like '%Foo B%'” Operadores lógicos e parênteses

“from User user where user.firstname like 'G%' and user.lastname like 'K%'”

Comparações

Page 201: Curso De Hibernate 3

Comparações

Operadores lógicos e parênteses “from User u where (u.firstname like 'G%' and

u.lastname like 'K%' ) or u.email in ('[email protected]', '[email protected]' )”

Coleções "from Item i where i.bids is not empty"

Page 202: Curso De Hibernate 3

Comparações

Funções podem ser chamadas a partir do HQL HQL permite a chamada de funções SQL na cláusula

WHERE Funções podem ser definidas pelo usuário

Depende do suporte do banco de dados Funções UPPER() e LOWER()

"from User u where lower(u.email) = '[email protected]'" Função SIZE()

from Item i where size(i.bids) > 3 E muitas outras...

Page 203: Curso De Hibernate 3

Comparações

Outras funções CONCAT(s1, s2) SUBSTRING(s, offset, length)

Offset começa a partir de 1 TRIM( [[BOTH|LEADING|TRAILING] s)

"from Item i where TRIM(BOTH i.name) = 'Computador'" LENGTH(s) LOCATE(search, s, offset)

Procura a localização de uma substring dentro de uma string

Page 204: Curso De Hibernate 3

Comparações

Outras funções CURRENT_DATE(), CURRENT_TIME(),

CURRENT_TIMESTAMP() Valores retornados são referentes ao SGBD

SECOND(d), MINUTE(d), HOUR(d), DAY(d), MONTH(d), YEAR(d)

Extraem os valores de um argumento temporal

Page 205: Curso De Hibernate 3

Ordenando o Resultado

A Cláusula ORDER BY é utilizada para ordenar o resultado "from User u order by u.name"

Ordem ascendente ou descendente Utiliza-se asc ou desc from User u order by u.username desc

Ordenando por mais de uma propriedade “from User u order by u.lastname asc, u.firstname asc”

Page 206: Curso De Hibernate 3

Junções

A habilidade de realizar junções é uma das principais forças do modelo relacional

Permite selecionar diferentes objetos associados e coleções em uma única consulta

Page 207: Curso De Hibernate 3

Inner Join

Contém somente os registros que estão relacionados com o outro lado da junção Contém somente os Itens que possuem Bids

Page 208: Curso De Hibernate 3

(left) Outer Join

Retorna todos os Itens Dados de Bid são preenchidos com NULL se não

houver uma correspondência

Page 209: Curso De Hibernate 3

Junção com HQL

Coluna de junção não precisar ser informada na consulta Informação é extraída do mapeamento

É necessário ser informado somente o nome da associação Nome do atributo que referencia a classe ou coleção

de classes Joins podem ser executados de duas maneiras

Join implícitos na Associação Join especificado na cláusula FROM

Page 210: Curso De Hibernate 3

Join Implícito na Associação

O Join é realizado através da associação entre duas entidades

Exemplo: “from Bid bid where bid.item.description like '%Foo%'” Bid é associado a Item através do atributo “item” Hibernate sabe que a associação está mapeada a partir da

chave estrangeira ITEM_ID da tabela BID Joins implícitos são sempre realizados através de

associações many-to-one ou one-to-one

Page 211: Curso De Hibernate 3

Join Implícito na Associação

Múltiplos joins são possíveis from Bid bid where bid.item.category.name like 'Laptop%'

Page 212: Curso De Hibernate 3

Join especificado na Cláusula FROM

Joins podem ser especificados explicitamente na cláusula FROM

Exemplo "select i from Item i join i.bids b where b.amount >

10" Aliases devem ser especificados na cláusula

FROM e utilizados na cláusula WHERE Cláusula SELECT é utilizada para que somente

Itens sejam retornados

Page 213: Curso De Hibernate 3

Join especificado na Cláusula FROM

Na consulta, um Item pode ser retornado mais de uma vez Uma para cada Bid associado Somente uma instância é utilizada

A consulta possui o mesmo formato para associações many-to-one e one-to-one

Page 214: Curso De Hibernate 3

Outer Joins

Para a utilização de Outer Joins utiliza-se a cláusula LEFT JOIN LEFT OUTER JOIN e RIGHT OUTER JOIN

também podem ser utilizados A cláusula WITH é utilizada para adicionar

restrições "select i from Item i left join i.bids b with

b.amount >= 9" Itens que não possuem Bids também são retornados

Page 215: Curso De Hibernate 3

Comparando Identificadores

Na Orientação a Objetos não são os identificadores, mas as referências ao objetos que são comparadas

Comparações podem ser feitas através dos atributos das entidades

"select i from Item i join i.bids b where i.seller = b.bidder" i.seller e b.bidder representam referências para a

entidade User Retorna os Itens em que o próprio vendedor deu um

lance

Page 216: Curso De Hibernate 3

Comparando Identificadores

Entidades também podem ser adicionadas como parâmetros de uma consulta

Query query = session.createQuery("from Item i where i.seller = :seller");

query.setEntity("seller", user);

Page 217: Curso De Hibernate 3

FIM...

Referências Livro Java Persistence with Hibernate

Edição revisada do livro Hibernate in Action Autores

Christian Bauer Gavin King

http://www.hibernate.org/ Documentação e Javadoc Fórum de discuções e dúvidas

JSR 220: Enterprise JavaBeans Version 3.0 Para as Annotations do pacote javax.persistence