Repositórios JPA no Projeto ecafeteria

Documentos relacionados
nome = n; cargo = c; salario = s; public void print() { System.out.println(nome cargo salario); public void aumento( double fator){

Mapeamento da herança em JPA

Computação II Orientação a Objetos

Universidade Federal de Uberlândia Faculdade de Computação Prof. Fabiano Azevedo Dorça Programação Orientada a Objetos II. Padrões de Projeto

Java para Desktop. Programação Orientada à Objetos 2 JSE

LÓGICA DE PROGRAMAÇÃO (JAVA) HERANÇA. Professor Carlos Muniz

JPA Com Hibernate. Paulo Ricardo Lisboa de Almeida. 1 Universidade Positivo

Mapeamento da herança em JPA

Lista 05 Herança. public class PessoaFisica extends Pessoa { private String RG; public PessoaFisica(){ super(); } public String getrg(){ return RG; }

Herança e Polimorfismo

C com introdução a OO

Abstract Factory. Prover uma interface para criar uma família de objetos relacionados ou dependentes sem especificar suas classes concretas

REST. Representational State Transfer. É um estilo arquitetural usado por muitas aplicações Web para estender as suas funcionalidades.

Herança e Propriedades

Classe Abstrata e Interface

Laboratório de programação II

Palavras Reservadas da Linguagem Java

LEIC-T LERC MEIC-T 2011/2012 1º Semestre Programação com Objetos 2012/01/07 11h00m 3/10

Recapitulando. Construtores: (Overload assinatura) public Circle() {...} public Circle(double x, double y, double r) {... }

Padrões de Projeto. Padrões de Projeto. Além dos 23 Padrões GoF. Os 23 Padrões de Projeto. Documentação de um Padrão. Classificação dos Padrões

Programação Orientada a Objetos Flávio de Oliveira Silva 144

Ex: carro_desportivo poderá ser uma subclasse de automóvel (carro_desportivo é_um automóvel)

Linguagem de Programação Orientada a Objeto Polimorfismo, Classes Abstractas e Interfaces

4 Conceito de Herança

Programação Orientada a Objetos. Vagner Luz do Carmo - Vluzrmos

Interfaces e Classes Abstratas

Computação II Orientação a Objetos

A B Classe Genérica D A C. Classe Especializada. Classe Especializada. Características Herdadas

Programação Orientada a Objetos

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Notas de Aula 09: Tratamento de exceções

p Imagine que um Sistema de Controle do Banco pode ser acessado, além dos Gerentes, pelos Diretores do Banco

UNIVERSIDADE FEDERAL DE MATO GROSSO DO SUL SISTEMAS DE INFORMAÇÃO - CÂMPUS DE COXIM FUNDAMENTOS EM ORIENTAÇÃO A OBJETOS

Herança. Prof. Andrea Garcia PROW II

Programação com Objectos 1º Teste Tipo 1º Semestre (90 minutos)

O que mudou no Demoiselle?

Universidade Federal de Uberlândia Faculdade de Computação Programação Orientada a Objetos II Prof. Fabiano Dorça. Padrão Observer (Observador)

Decorator e Composite. Nazareno Andrade (baseado no material de Hyggo Almeida)

POO29004 Programação Orientada a Objetos

Professor Leonardo Cabral da Rocha Soares Lattes:

POO29004 Programação Orientada a Objetos

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Avançando em Java com

Padrão J2EE Data Access Object (DAO)

Aula 9 Herança. Prof. Jefersson Alex dos Santos

Computação II (MAB 225)

Universidade da Beira Interior Cursos: Engenharia Informática, Matemática /Informática e Ensino da Informática

Programação Orientada a Objectos - P. Prata, P. Fazendeiro. Hierarquia de classes e mecanismo de ligação

Quando um programa viola as restrições semânticas da linguagem, a JVM assinala um erro ao programa, sob a forma de exceção.

Herança. Fátima L. S. Nunes Luciano A. Digiampietri Norton T. Roman SISTEMAS DE INFORMAÇÃO 1

TÉCNICAS DE ORIENTAÇÃO A OBJETOS

Programação Orientada a Objetos. Herança

Herança e Polimorfismo -Parte I - Mário Meireles Teixeira O exemplo DoME. Database of Multimedia Entertainment

Herança e Polimorfismo - Parte I -

Classes e Objetos. Sintaxe de classe em Java

Aula 10 POO 1 Classes Abstratas. Profa. Elaine Faria UFU

Composição e Herança. carro meucarro = new carro();

Conceitos de Programação Orientada a Objetos

Desenvolvimento Web II

Programação OO em Java. Profa Andréa Schwertner Charão DELC/CT/UFSM

Programação. Orientada a Objetos: Herança. Objetos. Relacionamento entre classes. Análise e Projeto Orientados a. Objetos

Interface vs. Implementação Herança vs. Composição

PROGRAMAÇÃO ORIENTADA A

Herança (parte 2) Redefinição de métodos AULA 11

Linguagem de Programação III

Linguagem de Programação. Diagrama de classes

Linguagem de Programação III

Introdução ao Java. Prof. Herbert Rausch Fernandes

Paradigmas de Linguagens de Programação. Suporte para Programação Orientada a Objeto

Introdução à orientação a objetos. João Tito Almeida Vianna 18/05/2013

JPA Demonstração das Estratégias Optimistic Locking e Pessimistic Locking

AspectJ. AspectJ. Extensões de AspectJ. Pontos de Junção. Exemplos de Pontos de Junção. Modelo de Pontos de Junção

Singleton e Adapter. Professor: Nazareno Andrade (baseado no material de Hyggo Almeida e Jacques Sauvé)

Herança. Universidade Católica de Pernambuco Ciência da Computação. Prof. Márcio Bueno.

Herança Sendo uma linguagem orientada a objetos Java oferece mecanismos para definir classes derivadas a partir de classes existentes; As classes deri

Herança. Prof. Fernando V. Paulovich 23 de agosto de 2010

Unidade: sobrecarga, construtores e herança

Programação Orientada a Objetos com Java. Prof. Júlio Machado

Programação Orientada por Objectos 2007/2008

Universidade Federal de Itajubá Instituto de Engenharia de Sistemas e Tecnologias da Informação-IESTI CCO002 Engenharia de Software

DCC004 - Algoritmos e Estruturas de Dados II

Utilizando Swing com Hibernate

Programação Orientada a Objetos Relacionamentos entre classes

12 Tipos Genéricos. Desenvolvimento OO com Java. Vítor E. Silva Souza

Conexão com Banco de Dados

Programação por Objectos. Java

UNIFEI Disciplina Professor

Criando uma aplicação web

Prof. Msc. Vladimir Camelo

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

Programação OO em Java. Profa Andréa Schwertner Charão DLSC/CT/UFSM

LEIC-A / MEIC-A 2007/2008 (1º

extendsé usado para indicar herança em JAVA

Programação Orientada a Objectos - P. Prata, P. Fazendeiro

9 Classes Abstractas e Interfaces

Instituto de Informática Estrutura de Dados II

Programação com Objectos. 2º Teste 2015/2016 1º Semestre

Transcrição:

Repositórios JPA no Projeto ecafeteria Um objeto EntityManager representa uma ligação à base de dados. Quando um objeto EntityManger é criado também é criado um objeto EntityTransaction associado ao EntityManager. Operações que modificam a base de dados têm de ser executadas dentro de uma transação. Para executar essas operações temos de iniciar a transação, executar as operações e fazer o commit da transação. As operações na base de dados são efetuadas por métodos existentes nos Repositórios. Se a operação a executar na base de dados afeta apenas um repositório, o início e commit da transação podem ser feitos no método existente no repositório. Assim controladores que usam apenas um agregado criam um Repositório (subclasse de) JpaTransactionalRepository, no qual cada método abre e fecha a transação working in a single immediate transaction mode. Se a operação a executar na base de dados afeta mais que um repositório, o início e commit da transação podem ser feitos no método do Controlador que usa os vários repositórios. Assim controladores que usam mais que um agregado criam Repositórios (subclasses de) JpaWithTransactionalContextRepository, no qual cada método não abre nem fecha a transação working within a TransactionalContext. Uma transação é iniciada no Controlador, a seguir são efetuadas operações nos vários Repositórios e no fim a transação é fechada no Controlador. A classe JpaTransactionalContext do projeto framework (package eapli.framework.persistence.repositories.impl.jpa) permite criar um objeto que representa uma ligação à base de dados e respetiva transação, assim como abrir e fechar a transação e fazer commit ou rollback. A linha de código seguinte cria um objeto que representa uma ligação à base de dados e respetiva transação: private final TransactionalContext TxCtx = PersistenceContext.repositories().buildTransactionalContext(); Classes base para Repositórios: public abstract class JpaBaseRepository<T, K extends Serializable> - implementa a interface IterableDataRepository - superclasse para Repositórios. - contém vários métodos CRUD que não abrem nem fecham a transação. public class JpaWithTransactionlContextRepository<T, K extends Serializable> - subclasse de JpaBaseRepository - recebe na criação um objeto TransactionalContext, através do qual obtém o objeto EntityManager e EntityManagerFactory. - não tem métodos CRUD.

public class JpaTransactionalRepository<T, K extends Serializable> - subclasse de JpaWithTransactionalContextRepository - recebe na criação o nome da unidade de persistência, cria o objeto TransactionalContext correspondente, e passa-o à superclasse. - tem os métodos delete(), create() e save(). - os métodos abrem e fecham a transação. public class CafeteriaJpaRepositoryBase<T, K extends Serializable> - subclasse de JpaTransactionalRepository - invoca o construtor da superclasse com o nome da unidade de persistência. - superclasse para Repositórios da aplicação ecafeteria cujas operações a executar na base de dados afetam apenas um repositório. public class JpaAutoTxRepository<T, K extends Serializable> - superclasse para Repositórios cujas operações podem afetar mais que um repositório. - tem dois atributos: repo, do tipo JpaBaseRepository, e autotx do tipo TransactionalContext. - pode receber na criação: 1) um objeto TransactionalContext que guarda no atributo autotx; cria repo do tipo JpaWithTransactionalContextRepository (métodos não abrem nem fecham a transação). 2) uma string com o nome da unidade persistência; o atributo autotx fica com o valor null e cria repo do tipo JpaTransactionalRepository (métodos abrem e fecham a transação). - JpaAutoTxRepository tem os métodos delete(), save(), findall(), findone(), count() e iterator() que delegam as ações no objeto repo.

O Problema Operações que modificam a base de dados têm de ser executadas dentro de uma transação. A realização de alguns casos de uso afeta apenas um repositório, mas para outros casos de uso as operações necessárias afetam mais que um repositório. Se as operações de um caso de uso afetam apenas um repositório o início e commit da transação podem ser feitos no método existente no repositório. Se as operações de um caso de uso afetam mais que um repositório o início e commit da transação podem ser feitos no método do Controlador e os repositórios usados devem ter métodos sem controlo transacional. Considerando todos os casos de uso e para cada caso de uso os repositórios usados, verificamos que existem: 1. repositórios que são sempre usados num contexto que não afeta outros repositórios, como por exemplo DishRepository, DishTypeRepository e MaterialRepository. 2. repositórios que podem ser usados quer num contexto que afeta outros repositórios, quer num contexto que não afeta outros repositórios, como por exemplo SignupRequestRepository, UserRepository e CafeteriaUserRepository. Design da solução Hierarquia de classes genéricas destinadas a criar repositórios: JpaBaseRepository<T, K extends Serializable> - classe genérica com várias operações CRUD sem controlo transacional. JpaWithTransactionlContextRepository<T, K extends Serializable> - classe genérica que recebe na criação um objeto TransacionalContext, também sem controlo transacional. JpaTransactionlRepository<T, K extends Serializable> - classe genérica com controlo transacional.

O projeto framework tem uma classe para servir de superclasse para os repositórios que são sempre usados num contexto que não afeta outros repositórios - JpaTransactionalRepository<T, K extends Serializable>. No entanto usa-se uma subclasse de JpaTransactionalRepository<T, K extends Serializable> em vez da própria superclasse para: Obter um tipo próprio para representar cada repositório herdando todas as funcionalidades de JpaTransactionalRepository; Ser possível estender o comportamento com métodos específicos para o repositório criado. Na aplicação ecafeteria optou-se por criar, no projeto ecafeteria.persistence.impl, a classe CafeteriaJpaRepositoryBase<T, K extends Serializable> como subclasse de JpaTransactionalRepository, para servir de superclasse às classes dos repositórios que são sempre usados num contexto que não afeta outros repositórios.

O projeto framework tem outra classe para representar os repositórios usados num contexto que afeta outros repositórios - JpaWithTransactionlContextRepository<T, K extends Serializable>. Mas como estes repositórios podem ser usados quer em contextos que afetam outros repositórios, quer em contextos que não afetam outros repositórios, e porque não seria modular usar classes diferentes em diferentes cenários para representar o mesmo repositório, o projeto framework tem outra classe JpaAutoTxRepository<T, K extends Serializable> para servir de superclasse a estes repositórios. Esta classe, em vez de usar herança, usa composição. A composição é mais flexível que a herança, porque enquanto a herança adiciona funcionalidades em tempo de compilação, a composição adiciona funcionalidades em tempo de execução. A classe JpaAutoTxRepository possui dois atributos, um atributo repo do tipo JpaBaseRepository e outro atributo autotx do tipo TransactionalContext. Quando JpaAutoTxRepository é usado num contexto que afeta outros repositórios: repo é um objeto do tipo JpaWithTransactionalContextRepository, e autotx é um objeto do tipo JpaTransactionalContext. Quando JpaAutoTxRepository é usado num contexto que não afeta outros repositórios: repo é um objeto do tipo JpaTransactionalRepository, e autotx é null. A classe JpaRepositoryFactory do projeto ecafeteria.persistence.impl (não incluída no diagrama acima) possui um método para criar cada um dos repositórios que são sempre usados num contexto que não afeta outros repositórios, e dois métodos para criar cada um

dos repositórios que podem ser usados quer em contextos que afetam outros repositórios, quer em contextos que não afetam outros repositórios: public class JpaRepositoryFactory implements RepositoryFactory { public DishTypeRepository dishtypes() { return new JpaDishTypeRepository(); public DishRepository dishes() { return new JpaDishRepository(); public MaterialRepository materials() { return new JpaMaterialRepository(); public SignupRequestRepository signuprequests() { return new JpaSignupRequestRepository( Application.settings().getPersistenceUnitName()); public SignupRequestRepository signuprequests(transactionalcontext autotx) { return new JpaSignupRequestRepository(autoTx); public UserRepository users() { return new JpaUserRepository( Application.settings().getPersistenceUnitName()); public UserRepository users(transactionalcontext autotx) { return new JpaUserRepository(autoTx); public JpaCafeteriaUserRepository cafeteriausers() { return new JpaCafeteriaUserRepository( Application.settings().getPersistenceUnitName()); public JpaCafeteriaUserRepository cafeteriausers( TransactionalContext autotx) { return new JpaCafeteriaUserRepository(autoTx); public TransactionalContext buildtransactionalcontext() { return JpaAutoTxRepository.buildTransactionalContext( Application.settings().getPersistenceUnitName(), Application.settings().getExtendedPersistenceProperties()); public DishReportingRepository dishreporting() { return new JpaDishReportingRepository();

Que classe usar para criar um Repositório? Se o Repositório a criar vai conter operações (a executar na base de dados) que afetam apenas um repositório (o início e commit da transação são feitos no método existente no repositório) devemos criá-lo como subclasse de CafeteriaJpaRepositoryBase. Se o Repositório a criar vai conter operações (a executar na base de dados) que nalguns cenários podem afetar apenas um repositório mas noutros cenários podem afetar mais que um repositório, devemos criá-lo como subclasse de JpaAutoTxRepository. Nos cenários em que as operações afetam mais que um repositório passamos ao construtor de JpaAutoTxRepository um objeto TransactionalContext. Este objeto permite-nos iniciar a transação no Controlador, ser usado nos repositórios para efetuar as operações na base de dados, e por fim fazer o commit da transação no Controlador. O objeto JpaAutoTxRepository cria um atributo repo do tipo JpaWithTransactionlContextRepository, que herda métodos CRUD de JpaBaseRepository, que não abrem nem fecham a transação, embora as operações sejam realizadas dentro de um contexto transacional cujo controlo está fora do repositório. Nos cenários em que as operações só afetam um repositório passamos ao construtor de JpaAutoTxRepository uma string com o nome da unidade de persistência. O objeto JpaAutoTxRepository cria um atributo repo do tipo JpaTransactionlRepository que contém métodos CRUD que abrem e fecham a transação. Assim os repositórios a criar podem ser de 3 tipos: 1. Repositórios cujas operações são sempre realizadas num contexto em que só é necessário aceder a um repositório dentro da transação => subclasse de CafeteriaJpaRepositoryBase. 2. Repositórios cujas operações podem ser realizadas quer num contexto em que só é necessário aceder a um repositório dentro da transação, quer num contexto em que é necessário aceder a mais que um repositório dentro da transação => subclasse de JpaAutoTxRepository. 2.1. Para os cenários em que é necessário aceder a mais que um repositório dentro de uma transação passamos ao construtor de JpaAutoTxRepository um objeto TransationalContext. O atributo repo do objeto JpaAutoTxRepository, no qual ele delega as operações na base de dados, será do tipo JpaWithTransactionalContextRepository. 2.2. Para os cenários em que só é necessário aceder a um repositório dentro de uma transação passamos ao construtor de JpaAutoTxRepository o nome da unidade de persistência. O atributo repo do objeto JpaAutoTxRepository, no qual ele delega as operações na base de dados, será do tipo JpaTransactionalRepository.

Exemplo: No caso de uso Aceitar ou Recusar Pedido de Registo o Controlador tem de modificar 3 repositórios: 1. Repos. de SignUpRequest para mudar o objeto do estado Pending para Accepted. 2. Repos. de User para criar o objeto User correspondente ao pedido. 3. Repos. de CafeteriaUser para criar o objeto CafeteriaUser correspondente ao User criado. Para modificar 3 repositórios dentro da mesma transação tem de criar um objeto TransactionalContext, criar cada um dos 3 Repositórios (subclasses de JpaAutoTxRepository) e passar-lhes o objeto TransactionalContext: JpaSignUpRequestRepository JpaUserRepository JpaCafeteriaUserRepository class AcceptRefuseSignupRequestController private final TransactionalContext TxCtx = PersistenceContext.repositories().buildTransactionalContext(); private final SignupRequestRepository signuprequestsrepository = PersistenceContext.repositories().signupRequests(TxCtx); private final UserRepository userrepository = PersistenceContext.repositories().users(TxCtx); private final CafeteriaUserRepository cafeteriauserrepository = PersistenceContext.repositories().cafeteriaUsers(TxCtx); public SignupRequest acceptsignuprequest(signuprequest thesignuprequest) { // explicitly begin a transaction TxCtx.beginTransaction(); SystemUser newuser = createsystemuserforcafeteriauser(thesignuprequest); createcafeteriauser(thesignuprequest, newuser); thesignuprequest = acceptthesignuprequest(thesignuprequest); // explicitly commit the transaction TxCtx.commit(); return thesignuprequest;