Swing <-> (RMI ou Spring) <-> Hibernate

Bom Dia pessoal do GUJ.

Estou criando um software que a camada de apresentação é Swing, e o acesso a banco de dados vai ser feito com o Hibernate, porém, eu gostaria de dividir essas camadas entre máquinas ou seja subiria o Hibernate no servidor e teria várias máquinas clientes acessando esse servidor.

Só não sei como fazer isso será que eu uso RMI ou é melhor Spring ou outro qualquer, bom eu não tenho experiencia com nenhum nem outro então gostaria de uma ajuda pra decidir.

Um dos principais problemas que eu não consigo imaginar solução é o Lazy-Loading do Hibernate porque em algumas telas deste sistema o Lazy é usado ativamente, ou seja a Tela abre uma Session faz um get (por exemplo em cliente) e depois vai fazendo vários gets em Atributos Many-To-One do Hibernate que são lazy (Ex: o endereço do cliente) e só depois que termina de exibir tudo é que a Session é fechada, existe solução para isso trabalhando em camadas???

Muito obrigado pela ajuda

O genesis tem por foco justamente resolver este tipo de problema. Além disso, a versão 3.0-EA3, em desenvolvimento, possui um binding Swing completo.

Existem algumas opções:

[list]Eager loading: nos casos de uso em que você precisará acessar relacionamentos lazy, você pode carregá-los explicitamente no servidor e já retornar os dados carregados.[/list]
[list]Acesso explícito através de chamadas remotas: ao invés de navegar os relacionamentos no cliente, os dados são carregados através de chamadas remotas explícitas conforme necessário.[/list]
[list]AOP: usando aspectos, você processa suas entidades persistentes de modo a fazer acesso implícito através de chamadas remotas.[/list]

O Spring tem um serviço REMOTE que substitui o RMI com algumas vantages. Se você vai implantar RMI, vale a pena dar uma olhada neste serviço.

Márcio

Estou bem tendencioso a usar EJB para Swing… pelo que lí a solução Remote do Spring com RMI (que é o caso), não suporta transação.

http://www.springframework.org/docs/reference/remoting.html

Quando pensamos no Swing, algumas vezes os Domain objects precisam ficar locados e com sessão aberta enquanto a tela viver. Aí, não estou conseguindo ver uma solução que fuja de Entity e Statefull. :cry:

A não ser que alguém aí tenha um coelho na cartola… :wink:

[quote=rafaelbtz]Bom Dia pessoal do GUJ.

Estou criando um software que a camada de apresentação é Swing, e o acesso a banco de dados vai ser feito com o Hibernate, porém, eu gostaria de dividir essas camadas entre máquinas ou seja subiria o Hibernate no servidor e teria várias máquinas clientes acessando esse servidor.

[/quote]

Outra coisa… leve em consideração se é realmente necessário ter um servidor de aplicações. Você realmente precisa dessa centralização? :?:

Não se esqueça que é possível conversar com o banco diretamente da sua estação (como você fazia com o Delphi, VB), não precisa de um servidor de aplicações. :wink:

Dá para fazer uma aplicação swing + hibernate sem precisar de App Server, vc só vai ter que gerenciar a transação na mão ou usando AOP.

Reforço o que o Rodrigo falou. Faça boa análise dos custos antes de se aventurar.

Se realmente vale a pena, recomendo que olhe o Genesis. É bem possível que ele atenda às necessidades de seu sistema.

Se não, outras duas soluções cruas e simples para remoting:
http://www.retrogui.com/cgi-bin/wiki_dualrpcserver.pl
http://www.quickserver.org/

[quote=LIPE]Reforço o que o Rodrigo falou. Faça boa análise dos custos antes de se aventurar.

Se realmente vale a pena, recomendo que olhe o Genesis.[/quote]

Na realidade, o genesis permite que você trabalhe com o Hibernate tanto em modo local ou remoto (com servidor de aplicações, por exemplo) usando exatamente o mesmo código no cliente.

Como o genesis resolve uma transação com um “long lived object”?

Exemplo, tenho uma classe Pedido mapeada no hibernate. Obtenho ela do servidor e atualizo essa instância na minha tela Swing, inclusive obtendo e atualizando as associações lazy. Determinado momento eu termino a transação e tudo é salvo [color=red]automaticamente[/color]. Funciona assim?

(não se esqueça que o Pedido é um POJO)…

O que você chama de “bidings”?

Não, e isso é uma péssima idéia, tanto na web como no desktop. Você nunca quer lockar as linhas fisicamente nem iniciar uma transação de banco num processo que espera pelo input do usuário. Na web você não mantém uma transação física aberta enquanto o usuário está vendo os dados. Seria possível fazer isso em modo local, mas você iria travar o sistema inteiro.

Na prática, o Hibernate já possui os recursos para resolver este problema, como versionamento, por exemplo.

Binding, a grosso modo, é uma ligação. O genesis permite que você popule JavaBeans a partir da sua tela sem a necessidade de listeners ou eventos. Basta que os nomes dos componentes coincidam com as propriedades para que eles estejam ligados. Mas o binding do genesis vai além: você pode ligar ações a métodos, popular tabelas através de instâncias de java.util.List, habilitar/desabilitar componentes, torná-los visíveis/invisíveis etc.

Isso depende. Depende do requisito e também depende da abstração que eu quero trabalhar. Pela minha idéia, se eu mexo no Cliente, estou mexendo num Domain Object, e nesse caso, deveria ser abstrato a idéia de salvar, principalmente num contexto transacional.

Cara, essa definição é empolgante… :lol: (rsrsrsrsrsrsrsr)

[quote=mister__m]
O genesis permite que você popule JavaBeans a partir da sua tela sem a necessidade de listeners ou eventos. Basta que os nomes dos componentes coincidam com as propriedades para que eles estejam ligados. Mas o binding do genesis vai além: você pode ligar ações a métodos, popular tabelas através de instâncias de java.util.List, habilitar/desabilitar componentes, torná-los visíveis/invisíveis etc.[/quote]
Ok, vc está me falando que ele entende POJOS? O genesis trabalha com as próprias classes do Swing (JLabel, JComboBox, JTextArea) ou são extensões?

(sua resposta vai me levar a baixar ou não o genesis para uma avaliação, estou a procura de um framework assim)

Como eu falei, é possível fazer isso em modo local de forma simples, mas a escalabilidade da aplicação fica limitada. Nenhum framework web ou desktop Java que eu conheça faz isso e essa é a razão.

Dando um exemplo bem direto, o genesis consegue manter um JavaBean como esse aqui:

@Form
public class FormExemplo {
     private String nome;
     private Date dataCadastro;

     /** getters e setters para as propriedades acima */
}

sincronizado com um componente Swing que contenha dois widgets chamados nome e dataCadastro. Você pode usar os componentes Swing standard e até mesmo usar os seus componentes. Para os seus componentes, basta você registrar binders para eles para que o genesis faça o seu trabalho.

EJB faz isso (logicamente só me ajuda na parte server, mas teoricamente a interface do Entity que chega para mim no client teria tudo que eu preciso e daria para usar os seus bidings, só não seria tão POJO assim).

Se trabalha independente é uma idéia legal e se encaixaria no cenário de plugar um long lived object… tem alguns frameworks por aí que precisam usar o XPTOLabel, XPTOButton, aí é amarração demais.

Na versão atual já está funcionando esses bindings?

Alguém confundiu as coisas. EJB não faz nada disso que nós falamos antes, a menos que eu não tenha entendido o que você disse. O que eu entendi do cenário que você descreveu foi:

[list]Usuário acessa funcionalidade que lista instâncias de X;[/list]
[list]Usuário seleciona uma instância de X para edição; a instância é lockada no banco nesse instante e inicia-se uma transação;[/list]
[list]Usuário edita os dados e pressiona salvar.[/list]
[list]Os dados são persistidos e a transação se encerra com commit.[/list]

Isso nenhum framework que eu conheça faz (nem deveria). Agora, se você tinha outra coisa em mente, por favor, explique de outra forma.

O binding Thinlet funciona desde a versão 2.0 (dezembro/2004). Para o binding Swing, um snapshot no ar que contém a implementação e uma aplicação demo atualizada que mostra os dois bindings sendo usados ao mesmo tempo com o mesmo modelo JavaBeans. Você pode encontrar essa versão aqui.

Neste momento estou trabalhando na atualização da documentação para cobrir o binding Swing.

[quote=rodrigoy]…a solução Remote do Spring com RMI (que é o caso), não suporta transação.
[/quote]

Onde viu isso? :roll:

Na própria documentação que enviei… ultimos parágrafos…

http://www.springframework.org/docs/reference/remoting.html

Olá rodrigoy,

Estranho isso, pois minha experiência com spring utlizando remoting e transações declarativas têm funcionado sem problemas…