Active record e transações

Galera, estou com uma duvida aqui e costaria da ajuda de vcs.
Em um projeto novo que estou trabalhando resolvemos usar o padrão active record e domain model.
Criamos uma classe chamada BasicActiveRecord que implementa os metodos salvar, excluir, alterar e buscarPorId. Todas as classes de negócio estendem desta classe e portanto todas as classes de negócio sabem se persistir.
Aqui começa a minha duvida. Como eu faço quando tiver que alterar dados de duas classes que não tem nenhum tipo de relacionamento e isso tiver que ser feito dentro de uma transação? Quem vai ser responsável por iniciar a transação, invocar os métodos de negócio das classes, verificar se houver alguma violação das regras e dar o commit ou o rollback?
Alguma dica?

valeu.

Acho que vc deve delegar p/ alguem fazer isso. Criar um objeto que vai receber seus objetos e controlar isso p/ vc. Acredito que os objetos persistentes não devem conhecer essa responsabilidade. Vc continua chamando os metodos save dos objetos, mas dentro de um outro obj que vai controlar a transação.
É o que consigo pensar agora.

[]'s

[quote=llvaleriano]Galera, estou com uma duvida aqui e costaria da ajuda de vcs.
Em um projeto novo que estou trabalhando resolvemos usar o padrão active record e domain model.
Criamos uma classe chamada BasicActiveRecord que implementa os metodos salvar, excluir, alterar e buscarPorId. Todas as classes de negócio estendem desta classe e portanto todas as classes de negócio sabem se persistir.
Aqui começa a minha duvida. Como eu faço quando tiver que alterar dados de duas classes que não tem nenhum tipo de relacionamento e isso tiver que ser feito dentro de uma transação? Quem vai ser responsável por iniciar a transação, invocar os métodos de negócio das classes, verificar se houver alguma violação das regras e dar o commit ou o rollback?
Alguma dica?

valeu.[/quote]

Existe um padrão chamado WorkUnit para resolver isso. Mas ActiveRecord não foi feito para usar em transações. É melhor DataMapper ou Store

Esse projeto tem pretensão de crescer muito? Active Record em Java sempre fica bem estranho quando o número de classes começa a crescer. E se o projeto for ter lógica de acesso a dados com alguma complexidade, o Active Record vira uma grande confusão.

Na teoria e nos exemplos, fica bem bonitinho, mas no mundo real, fica bem fedorento.

Sobre as transações, você pode usar interceptadores/filtros (WebWork, Tomcat) ou AOP (Spring…). Resolve muito bem o problema.

O projeto não é muito grande não, mas tem muita complexidade nas regras de negócio. A principio não irá crescer muito além do escopo que já foi definido, mas nada impede que isso aconteça.
O problema de usar filtros é que amarro a implementação de uma regra da camada de modelo com a requisição http. Se precisar criar uma nova visão q não seja web isso pode gerar problemas.

[quote=llvaleriano]O projeto não é muito grande não, mas tem muita complexidade nas regras de negócio. A principio não irá crescer muito além do escopo que já foi definido, mas nada impede que isso aconteça.
O problema de usar filtros é que amarro a implementação de uma regra da camada de modelo com a requisição http. Se precisar criar uma nova visão q não seja web isso pode gerar problemas. [/quote]

Nesse caso use WorkUnit. Sem saber como vc faz a persitencia é o máximo que se pode dizer.

O projeto ainda está na fase de elaboração, e a arquitetura está sendo definida. Ainda há tempo de se mudar de estratégia.
Neste caso, qual seria mais indicada?

Já sabemos que vamos modelar de acordo com o padrão Domain Model, e para alguns casos de uso, existe uma lógica de negócio com um nivel médio de complexidade (na maior parte do tempo temos que verificar o estado de alguns objetos e verificar se algumas operações podem ser executadas).

Qual seria a melhor alternativa, data mapper ou unit of work?

[quote=llvaleriano]O projeto ainda está na fase de elaboração, e a arquitetura está sendo definida. Ainda há tempo de se mudar de estratégia.
Neste caso, qual seria mais indicada?

Já sabemos que vamos modelar de acordo com o padrão Domain Model, e para alguns casos de uso, existe uma lógica de negócio com um nivel médio de complexidade (na maior parte do tempo temos que verificar o estado de alguns objetos e verificar se algumas operações podem ser executadas).

Qual seria a melhor alternativa, data mapper ou unit of work?
[/quote]

Domain Model é muito bonito na teoria, mas na prática são outros 500…
Se vc pode mudar a arquitetura então opte por JPA que lhe permite fazer tudo isso facilmente. Ele já tem um data mapper embutido e as transações vc pode controlar explicitamente.

Mas como fica a distribuição deste modelo em camadas?
Não tenho experiencia com jpa, só fiz alguns mapeamentos usando annotations para experimentar a novidade.
Qual seria o caminho das pedras?
Tenho minhas classes de negócio modeladas, vou fazer o mapeamento destas classes usando hibernate annotations.
Imagino que iremos usar uma fachada para centralizar/simplicar as chamadas aos métodos que estão programados nas classes de negócio. As chamadas para a fachada serão feitas em actions do struts.
A duvida é: Onde vai ficar o controle das transações? quem será responsável por persistir os dados?

Valeu

[quote=llvaleriano]Mas como fica a distribuição deste modelo em camadas?
Não tenho experiencia com jpa, só fiz alguns mapeamentos usando annotations para experimentar a novidade.
Qual seria o caminho das pedras?
Tenho minhas classes de negócio modeladas, vou fazer o mapeamento destas classes usando hibernate annotations.
Imagino que iremos usar uma fachada para centralizar/simplicar as chamadas aos métodos que estão programados nas classes de negócio. As chamadas para a fachada serão feitas em actions do struts.
A duvida é: Onde vai ficar o controle das transações? quem será responsável por persistir os dados?

Valeu[/quote]

Pera ai! façade com domain model ? Ou bem que usa um ou bem que usa o outro. Se vc já abandonou a ideia do domain model, ok , mas se não, parece que tá havendo uma confusão ai.

A estrutura padrão para camadas é:
Apresentação : Command e BusinessDelegate (passa instruções ao servidor)
Controle : WorkUnit (controla inicio/fim da transação)
Modelo : Domain Model (as classes normais com anotações)
Persistencia: DAO (implementado de forma a suportar transações ad doc e mapeamento do Domain Model)

As actions são comand businessdelegate e workunit ao mesmo tempo.
As classes devidamente anotadas são o domain model. O JPA ou o Hibernate são o DAO.

Sergio, gostaria muito de conversar mais sobre esse assunto contigo.
Tem como vc adicionar meu contato no msn pra a gente poder ter uma conversa um pouco mais dinamica? Depois eu posto a conversa aqui no guj.

valeu,

Léo

llvaleriano@hotmail.com

Não existe nenhum problema em haver Façades no Domain Model.

Eric Evans, inclusive, utiliza o conceito de Services como Façades desta Camada.

Deixa eu explicar melhor então, já que parece que tá havendo confusão.
Esta fachada, ao meu ver, pode sim ser usada junto com domain model. A fachada apenas abstrai o fluxo de iterações necessárias para realizar uma determinada função do sistema. Ela não executa nenhuma regra, apenas centraliza as chamadas para os objetos de dominio que possuem tais regras. É o que Martin Fowler chama de service layer.

Algum problema nesta implementação?

valeu

Léo

Não há problema. Façade é um design pattern aplicável em diversas ocasiões e camadas.

[quote=llvaleriano]Deixa eu explicar melhor então, já que parece que tá havendo confusão.
Esta fachada, ao meu ver, pode sim ser usada junto com domain model. A fachada apenas abstrai o fluxo de iterações necessárias para realizar uma determinada função do sistema. Ela não executa nenhuma regra, apenas centraliza as chamadas para os objetos de dominio que possuem tais regras. É o que Martin Fowler chama de service layer.

Algum problema nesta implementação?
[/quote]

Então chame pelo nome certo :wink: Service Layer não é a mesma coisa que Façade … mas isso são detalhes. A questão que me levou à pergunta não tme a ver com nome mas com a inclusão de uma camada extra
Eu tinha entendido que vc ia usar actions do struts e domain model , nesse caso a lógia dentro do action é assim

Pedido p = ... // obtém pedido através do action form etc etc 
p.fatura();

Service seria assim

// dentro do action
Service s = .. //obtém serviço 
Pedido p = .. // obtém pedido da mesma forma que antes

s.fatura (p); 

// dentro do service

public void fatura (Pedido p ){

 p.fatura();
}

Veja que com Domain Model as operações estão nos objetos e portanto, se o ambiente não é destribuido (web não é, e struts é web) não ha necessidade de service. Que service vc está imaginando que não cabe dentro de um dos objetos do dominio ? Com qual finalidade vc usaria façade/service ?