Course Hibernate 2008

39
HIBERNATE Christiano Milfont

description

Curso sobre hibernate

Transcript of Course Hibernate 2008

Page 1: Course Hibernate 2008

HIBERNATE

Christiano Milfont

Page 2: Course Hibernate 2008

Table per class

Sumário

Ciclo de vida Configuração Mapeamento

Relacionamentos

Queries

Herança

Transaction

Arquitetura

Cascade

EntityPropriedadesFetch

One to One

Many to OneOne to Many

Many to Many

Consultas PolimórficasHQLQueries, NamedQueries e Native QueriesCriteria e Query By Example

Single table per classJoined

Page 3: Course Hibernate 2008

Arquitetura

O Hibernate é uma Engine com o propósito de mapear o modelo orientado a objetos das classes do domínio da aplicação com o modelo entidade-relacional do banco de dados e controlar o ciclo de persistência desses objetos entre os dois ambientes distintos.

Page 4: Course Hibernate 2008

Arquitetura

O Hibernate é uma camada de persistência que implementa diversos design patterns, entre eles DAO, Work-Of-Unit, Query-By-Example.

O Hibernate pode ser usado como implementação da especificação JPA (JSR220) da JEE apesar que o Hibernate possui maior maturidade e elementos mais robustos como ORM.

Page 5: Course Hibernate 2008

ArquiteturaSessionFactory (org.hibernate.SessionFactory)

SessionFactory é um cache Thread-safe (imutável) de mapeamentos compilados para um único banco de dados. Usualmente uma aplicação tem uma única SessionFactory. O comportamento de uma SessionFactory é controlado pelas propriedades fornecidas na configuração.

Session (org.hibernate.Session)

Uma Session é uma representação de uma conversa entre a aplicação e o banco de dados. Ela envolve uma conexão JDBC e pode ser usada para manter as operações. Ele também possui um cache de objetos persistentes, utilizado quando se está navegando entre os objetos atachados ou buscando objetos pelo identificador.

Transaction (org.hibernate.Transaction)

Transactions são usadas para denotar uma unidade de trabalho atômica (atomic unit of work) que pode ser salva (committed) ou desfeita (rolled back). Uma transaction pode ser iniciada pela chamada session.beginTransaction() que realmente usa um mecanismo de transação subjacente a JDBC, JTA ou CORBA. Uma Session pode abranger várias Transactions em alguns casos.

Page 6: Course Hibernate 2008

ArquiteturaQuery (org.hibernate.Query)

Query é uma representação orientada a objetos de uma query SQL.

Criteria (org.hibernate.Criteria)

Criteria é uma API simplificada para obtenção de entidades e suas composições com base em objetos de critérios e restrições. Uma Session é uma fábrica de Criteria. A melhor forma de usar orientação a objetos com Hibernate é usando Criteria.

SQLQuery (org.hibernate.SQLQuery)

Representação de consultas em SQL para obtenção da lista de objetos injetada a partir da transformação do resultado pelo mapeamento da SessionFactory.

Page 7: Course Hibernate 2008

ArquiteturaHibernate como implementação para JPA

Page 8: Course Hibernate 2008

Ciclo de vida

O ciclo de vida de um objeto controlado pelo Hibernate se resume em 3 estados: persistente, transient e desatachado.

Page 9: Course Hibernate 2008

Ciclo de vida

Persistente é quando uma instância está gerenciada pelo Hibernate após de ter sido persistido ou obtido a partir do banco.Uma entidade persistente tem uma representação no banco de dados e um valor de identificação válido.É uma representação que existe enquanto uma Sessin for válida.

Page 10: Course Hibernate 2008

Ciclo de vida

Transient é um objeto que não está associado a uma Session.Não tem uma representação no banco de dados e nenhum valor de identificação associado.Objetos transients são previamente instancias de objetos Persistentes caso seja usado em uma operação na Session.

Page 11: Course Hibernate 2008

Ciclo de vida

Desatachado é um objeto que perdura fora de uma sessão.Um objeto que foi persistido porém a session foi fechada.

Ele tem uma representação no banco de dados com um valor de identificação válido associado porém sem estado controlado pelo Hibernate.

Page 12: Course Hibernate 2008

Configuração

AnnotationConfiguration annot = new AnnotationConfiguration();annot.addPackage("br.com.triadworks.doc");annot.addAnnotatedClass(Documento.class);annot.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLDialect");annot.setProperty("connection.url","jdbc:mysql://localhost:3306/docs");annot.setProperty("connection.driver_class","com.mysql.jdbc.Driver");annot.setProperty("connection.username","root");annot.setProperty("connection.password","123");SessionFactory fabrica = annot.configure().buildSessionFactory();Session session = fabrica.openSession();Transaction tx = session.beginTransaction();Documento doc = new Documento(10);session.load(doc, doc.getId());tx.commit();session.close();

A configuração principal do Hibernate pode ser em arquivos XML ou programática ou ainda na combinação dos dois modos. Temos duas classes principais de configuração, a Configuration (que busca mapeamentos em XML) e a AnnotationConfiguration (que busca mapeamentos em anotações).

Page 13: Course Hibernate 2008

Mapeamento

A anotação @Entity define uma classe gerenciada pelo Hibernate que é uma representação de uma entidade relacional, se o nome da classe for o mesmo da tabela não há necessidade de usar a anotação @Table em conjunto.

@Entity@Table(name = "tw_documentos")public class Documento {

O mapeamento pode ser via XML ou usando anotações.

A anotação @Column define uma propriedade que é uma representação de uma coluna no banco de dados.

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

O hibernate extende as anotações da JPA e oferecem um conjunto maduro de características de mapeamento objeto-relacional para controle preciso.

Entity e propriedades

Page 14: Course Hibernate 2008

Mapeamento

O hibernate habilita alguns tipos de estratégias de Fetching:

Join Fetching – Obtem instancia associada ou coleções em um único select usando OUTER JOIN.

Select Fetching – um select é executado para cada entidade associada a consulta.

Subselect Fetching – um subselect é usado para obter as outras instancias associadas ao select principal.

Os tipos de Fetch são:

Eager load – Uma associação, coleção ou atributo é carregado imediatamente quando o objeto principal é carregado.

Lazy Load – uma coleção ou propriedade é carregada somente quando for invocada. Esse modo é padrão para coleções.

@OneToOne(targetEntity=Post.class,fetch=FetchType.LAZY)@JoinColumn(name="documento_content", nullable=true)private Post content;

Fetch

Page 15: Course Hibernate 2008

Mapeamento

O hibernate oferece algumas operações de Cascade a mais que o JPA, são elas:PERSIST, MERGE, REMOVE, REFRESH, DELETE, SAVE_UPDATE, REPLICATE, DELETE_ORPHAN, LOCK, EVICT

Algumas observações devem ser consideradas:

DELETE_ORPHAN é aplicado somente para associações com anotações @OneToMany, indica que o método delete()/remove() remove os itens filhos de um pai que foi excluído caso seja anotado com esse tipo. SAVE_UPDATE é indicado quando se usa Hibernate ao inves de PERSIST como manda a especificação.

@OneToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})public Collection<Employer> getEmployers()

Cascade

Page 16: Course Hibernate 2008

Herança Table per class

@Entity@Table(name = "tw_documentos")@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)public class Documento

@Entity@Table(name = "tw_documentos_apoio")public class Apoio extends Documento

Estratégia onde cada Classe é salva em uma tabela distinta com todas suas propriedades.

Page 17: Course Hibernate 2008

Herança Single Table per class

@Entity@Table(name = "tw_documentos")@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(

name="DOC_TYPE",

discriminatorType=DiscriminatorType.STRING)@DiscriminatorValue("DOCUMENTO")public class Documento@Entity@DiscriminatorValue("APOIO")public class Apoio extends Documento

Estratégia onde todas as propriedades das classes e subclasses são salvas em uma mesma tabela

Page 18: Course Hibernate 2008

Herança Joined

@Entity@Table(name = "tw_documentos")@Inheritance(strategy=InheritanceType.JOINED)public class Documento

@Entity@Table(name = "tw_documentos_apoio")@PrimaryKeyJoinColumn(name="DOC_ID")public class Apoio extends Documento

Estratégia onde as propriedades específicas das subclasses são salvas em uma tabela distinta, juntas pela chave primária da superclasse mapeada como chave estrangeira

Page 19: Course Hibernate 2008

Relacionamentos One to One

O relacionamento um-para-um representa uma composição onde um objeto é propriedade de outro. Temos 3 formas de relacionamento do tipo One-to-One:1 - Quando o mesmo id é compartilhado entre as duas entidades; 2 - Quando o id da composta é uma fk da agregada;3 - Quando existe uma terceira tabela que armazena a referencia entre os dois ids.

Page 20: Course Hibernate 2008

Relacionamentos One to One

@Entitypublic class Body { @Id public Long getId() { return id; } @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn public Heart getHeart() {return heart;} ...}

@Entitypublic class Heart { @Id public Long getId() { ...}}

Quando o mesmo id é compartilhado entre as duas entidades

Page 21: Course Hibernate 2008

Relacionamentos One to One

@Entitypublic class Customer implements Serializable { @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name="passport_fk") public Passport getPassport() { ... }

@Entitypublic class Passport implements Serializable { @OneToOne(mappedBy = "passport") public Customer getOwner() { ...}

Quando o id da composta é uma fk da agregada.

Page 22: Course Hibernate 2008

Relacionamentos One to One

@Entitypublic class Customer implements Serializable { @OneToOne(cascade = CascadeType.ALL) @JoinTable(name = "CustomerPassports", joinColumns = @JoinColumn(name="customer_fk"), inverseJoinColumns =@JoinColumn(name="passport_fk") ) public Passport getPassport() { ...}

@Entitypublic class Passport implements Serializable { @OneToOne(mappedBy = "passport") public Customer getOwner() { ...}

Quando existe uma terceira tabela que armazena a referencia entre os dois ids.

Page 23: Course Hibernate 2008

Relacionamentos Many to One

O relacionamento muitos-para-um é usado em grande parte aliado de one-to-one no sentido inverso de carregamento. Observe no código que a anotação @JoinColumn é opcional, usada apenas caso não haja referência de anotação @OneToOne no objeto Company.

@Entity()public class Flight implements Serializable { @ManyToOne(cascade = {CascadeType.PERSIST} ) @JoinColumn(name="COMP_ID") public Company getCompany() { return company; } ...}

Page 24: Course Hibernate 2008

Relacionamentos Coleções: One to Many e Many to Many

O relacionamento de coleções em propriedades de objetos suportam os tipos List, Map e Set. A anotação OneToMany é recomendada a ser bidirecional mas pode ser apenas no objeto composto. @Entitypublic class Troop { @OneToMany(mappedBy="troop") public Set<Soldier> getSoldiers() { ...}

@Entitypublic class Soldier { @ManyToOne @JoinColumn(name="troop_fk") public Troop getTroop() { ...}

Page 25: Course Hibernate 2008

Relacionamentos One to Many

O relacionamento OneToMany assim como o OneToOne também tem 3 formas de mapeamento:

1 – Bidirecional2 – Unidirecional3 – Unidirecional com Join Table

Page 26: Course Hibernate 2008

Relacionamentos One to Many bidirecional

A anotação OneToMany é realizada tanto no lado “owner” do relacionamento (aquele que é composto pela coleção) quanto no lado das unidades da coleção.

@Entitypublic class Troop { @OneToMany(mappedBy="troop") public Set<Soldier> getSoldiers() { ...}

@Entitypublic class Soldier { @ManyToOne @JoinColumn(name="troop_fk") public Troop getTroop() { ...}

Page 27: Course Hibernate 2008

Relacionamentos One to Many unidirecional

A anotação OneToMany é realizada apenas no lado “owner” do relacionamento (aquele que é composto pela coleção).@Entitypublic class Customer implements Serializable { @OneToMany(cascade=CascadeType.ALL,

fetch=FetchType.EAGER) @JoinColumn(name="CUST_ID") public Set<Ticket> getTickets() { ...}

@Entitypublic class Ticket implements Serializable { ... //no bidir}

Page 28: Course Hibernate 2008

Relacionamentos One to Many unidirecional com Join Table

Essa anotação funciona como o OneToOne com uma terceira tabela para indexação entre as entidades@Entitypublic class Trainer { @OneToMany @JoinTable( name="TrainedMonkeys", joinColumns = @JoinColumn(name="trainer_id"), inverseJoinColumns = @JoinColumn(name="monkey_id") ) public Set<Monkey> getTrainedMonkeys() { ...}

@Entitypublic class Monkey { ... //no bidir}

Page 29: Course Hibernate 2008

Relacionamentos Many to Many

@Entitypublic class Employer implements Serializable { @ManyToMany( targetEntity=org.milfont.Employee.class, cascade={CascadeType.PERSIST, CascadeType.MERGE} ) @JoinTable( name="EMPLOYER_EMPLOYEE", joinColumns=@JoinColumn(name="EMPER_ID"), inverseJoinColumns=@JoinColumn(name="EMPEE_ID") ) public Collection getEmployees() { return employees; }}

Essa anotação funciona tanto unidirecional quanto bi, é indicado usar a anotação @JoinTable sempre para indicar o mapeamento entre as tabelas

Page 30: Course Hibernate 2008

Relacionamentos Many to Many

@Entitypublic class Employee implements Serializable { @ManyToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "employees", targetEntity = Employer.class ) public Collection getEmployers() { return employers; }}

Cont.

Page 31: Course Hibernate 2008

Transaction Ambiente não gerenciado

Session sess = factory.openSession();Transaction tx = null;try { tx = sess.beginTransaction();

// do some work ...

tx.commit();}catch (RuntimeException e) { if (tx != null) tx.rollback(); throw e; // or display error message}finally { sess.close();}

Page 32: Course Hibernate 2008

Queries Consultas polimorficas

Documento doc = new Documento();Apoio apoio = new Apoio(); // Apoio extends Documento...repository.open(doc);repository.open(apoio);

Class Repository {public void open(Documento doc){

Session session = ... Transaction tx = session.beginTransaction();session.load(doc, doc.getId());tx.commit();session.close();

}...

Todas as consultas do Hibernate são polimorficas pro natureza e entendem a herança entre os objetos

Page 33: Course Hibernate 2008

Queries HQL

select custfrom Product prod, Store store inner join store.customers custwhere prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) and prod = all elements(cust.currentOrder.lineItems)

A linguagem HQL é uma intermediária entre o SQL tanto Ansi quanto proprietário que trabalha com objetos e métodos ao inves de entidades e colunas

Page 34: Course Hibernate 2008

Queries HQL

// HQLselect cust from Product prod, Store store inner join store.customers cust where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney') and prod = all elements(cust.currentOrder.lineItems)

//SQLSELECT cust.name, cust.phone, cust.id, cust.current_orderFROM customers cust, stores store, locations loc, store_customers sc, product prodWHERE prod.name = 'widget' AND store.loc_id = loc.id AND loc.name IN ( 'Melbourne', 'Sydney' ) AND sc.store_id = store.id AND sc.cust_id = cust.id AND prod.id = ALL( SELECT item.prod_id FROM line_items item, orders o WHERE item.order_id = o.id AND cust.current_order = o.id)

Page 35: Course Hibernate 2008

Queries Queries

Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");q.setProperties(fooBean); // fooBean tem getName() e getSize()List foos = q.list();

A entidade Query trabalha com a linguagem HQL para fazer a execução de sentenças e obter uma representação de objetos

Page 36: Course Hibernate 2008

Queries NamedQuery e NamedQueries

@Entity@NamedQuery(name="night.moreRecentThan", query="select n from Night n where n.date >= :date")public class Night { ... }

public class MyDao { doStuff() { Query q = s.getNamedQuery("night.moreRecentThan"); q.setDate( "date", aMonthAgo ); List results = q.list(); ... } ...}

São consultas definidas em anotações ou xml de escopo global que pode ser usado por qualquer objeto Query

Page 37: Course Hibernate 2008

Queries Native Query

@NamedNativeQuery(name="implicitSample", query="select * from SpaceShip", resultClass=SpaceShip.class)public class SpaceShip {

São consultas do tipo NamedQuery realizadas em sintaxe nativa SQL. Indicado para realizar operações proprietárias que o Hibernate não resolva ou refinar uma sentença

Page 38: Course Hibernate 2008

Queries Criteria

List cats = sess.createCriteria(Cat.class) .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) ) .add( Restrictions.disjunction() .add( Restrictions.isNull("age") ) .add( Restrictions.eq("age", new Integer(0) ) ) .add( Restrictions.eq("age", new Integer(1) ) ) .add( Restrictions.eq("age", new Integer(2) ) ) ) ) .list()

É uma API intuitiva que se baseia na orientação a objetos para criar uma instancia de consulta com base em restrições

Page 39: Course Hibernate 2008

Queries Query By Example

Criteria criterio = session.createCriteria(Evento.class);criterio.setProjection(Projections.rowCount());criterio.createCriteria("gestor")

.add(Example .create(tipo.getGestor())

.excludeZeroes()

.IgnoreCase()

.enableLike(MatchMode.ANYWHERE));

É uma busca baseada em um filtro como exemplo. Um objeto é populado de tal forma que seja a representação de todo um conjunto de elementos semelhantes